Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Diego Moco

Importar XML para o banco de dados

Recommended Posts

Olá!

 

Estou importando um xml para o banco de dados, porém o dado Lap importa tudo em um campo só, assim:

 

Id Name CarType position Lap Laps Pitstops FinishStatus
1 Diego Jacometti F1BC Formula Light 1 --.----108.6030107.8197--.---- 4 1

 

Mas na verdade eu quero que fique separado em 2 registros, tipo assim:

 

Id Name CarType position Lap Laps Pitstops FinishStatus
1 Diego Jacometti F1BC Formula Light 1 --.----108.6030--.---- 4 1

2 Diego Jacometti F1BC Formula Light 1 --.----107.8197--.---- 4 1

 

Tem como isso? abaixo segue o trecho do xml e mais abaixo o sql que uso pra importar

 

Diego Jacometti
1
EQUIPE38FL.VEH
00000000 00000000
Equipe38
F1BC Formula Light
F1BC Formula Light
1000
Supersoft Compound
1
1
1
0
0
1
--.----
108.6030
107.8197
--.----
107.8197
4
1
Finished Normally
PlayerControl,ABS=1,Clutch,AutoBlip

 

[inline]USE [F1BC]
GO

-- Criação de tabela temporária

IF OBJECT_ID('tempdb..#RaceResult') IS NOT NULL
BEGIN
DROP TABLE #RaceResult
END

CREATE TABLE #RaceResult (
[Name] [varchar](50) NOT NULL,
[CarType] [varchar](50) NOT NULL,
[position] [varchar](50) NOT NULL,
[Lap] [varchar](50) NOT NULL,
[Laps] [varchar](50) NOT NULL,
[Pitstops] [varchar](50) NOT NULL,
[FinishStatus] [varchar](50) NULL,
)


-- Carregando os dados a partir do arquivo XML

INSERT INTO #RaceResult
(Name
,CarType, position,Lap,Laps,Pitstops,FinishStatus)
SELECT
X.Driver.query('Name').value('.', 'VARCHAR(50)'),
X.Driver.query('CarType').value('.', 'VARCHAR(50)'),
X.Driver.query('Position').value('.', 'VARCHAR(50)'),
X.Driver.query('Lap').value('.', 'VARCHAR(50)'),
X.Driver.query('Laps').value('.', 'VARCHAR(50)'),
X.Driver.query('Pitstops').value('.', 'VARCHAR(50)'),
X.Driver.query('FinishFinishStatus').value('.', 'VARCHAR(50)')

FROM
(
SELECT CONVERT(xml, X, 2)
FROM OPENROWSET(
BULK 'C:\Users\Diego\Desktop\F1BC\TestesF1BC\Race1.xml',
SINGLE_BLOB) AS T(X)
) AS T(X)
CROSS APPLY X.nodes('rFactorXML/RaceResults/Qualify/Driver') AS X(Driver);


-- Incluindo as informações na tabela piloto

DECLARE @Name VARCHAR(50)
DECLARE @CarType VARCHAR(50)
DECLARE @position VARCHAR(50)
DECLARE @Lap VARCHAR(50)
DECLARE @Laps VARCHAR(50)
DECLARE @Pitstops VARCHAR(50)
DECLARE @FinishStatus VARCHAR(50)

DECLARE crRaceResult CURSOR FOR
SELECT Name
,CarType,position, Lap,Laps,Pitstops,FinishStatus
FROM #RaceResult
ORDER BY position

OPEN crRaceResult

FETCH NEXT FROM crRaceResult INTO
@Name, @CarType, @position, @Lap, @Laps, @Pitstops, @FinishStatus

BEGIN TRANSACTION -- Inicia uma nova transação

WHILE @@FETCH_STATUS = 0
BEGIN
--IF (LTRIM(RTRIM(@Name)) = '')
-- SET @Name = NULL

IF (NOT EXISTS(SELECT 1 FROM dbo.RaceResult WHERE Name = @Name))
BEGIN
INSERT INTO dbo.RaceResult
(Name
,CarType,position, Lap,Laps,Pitstops,FinishStatus
)
VALUES
(@Name
,@CarType
,@position
,@Lap
,@Laps
,@Pitstops
,@FinishStatus
)
END
ELSE
BEGIN
UPDATE dbo.RaceResult
SET Name = @Name
,CarType = @CarType
,position = @position
,Lap = @Lap
,Laps = @Laps
,Pitstops = @Pitstops
,FinishStatus = @FinishStatus
WHERE Name = @Name
END

FETCH NEXT FROM crRaceResult INTO
@Name, @CarType, @position, @Lap, @Laps, @Pitstops, @FinishStatus
END

CLOSE crRaceResult

DEALLOCATE crRaceResult


-- Verifica a ocorrência de erros e, em caso negativo, confirma
-- a transação iniciada anteriormente

IF (@@ERROR = 0)
BEGIN
COMMIT TRANSACTION
END
ELSE
BEGIN
ROLLBACK TRANSACTION
END


[/inline]

Compartilhar este post


Link para o post
Compartilhar em outros sites

O XML não apereceu com a tags, só entrou os textos

 

Fiz um exemplo que você deverá entender

 

declare @x xml ='<dados>
<Name>Diego Jacometti</Name>
<lap>108.6030</lap>
<lap>107.8197</lap>
</dados>'


select 
	 tb.fd.value('../Name[1]', 'varchar(50)')
	,tb.fd.value('.', 'varchar(50)')
from @x.nodes('dados/lap') tb(fd)

Uma dúvida os dois valores de lap vem em duas tags como no exemplo ?? Se for é só adicionar os demais campos

 

Opinião:

 

Eu prefiro usar variáveis do tipo tabela à tabelas temporárias, se vc precisa dos dados apenas dentro do procedimento terá um desempenho bem melhor conforme a massa de dados vai crescendo.

 

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá

 

O XML não apereceu com a tags, só entrou os textos

 

Fiz um exemplo que você deverá entender

 

declare @x xml ='<dados>
<Name>Diego Jacometti</Name>
<lap>108.6030</lap>
<lap>107.8197</lap>
</dados>'


select 
	 tb.fd.value('../Name[1]', 'varchar(50)')
	,tb.fd.value('.', 'varchar(50)')
from @x.nodes('dados/lap') tb(fd)

Uma dúvida os dois valores de lap vem em duas tags como no exemplo ?? Se for é só adicionar os demais campos

 

Opinião:

 

Eu prefiro usar variáveis do tipo tabela à tabelas temporárias, se vc precisa dos dados apenas dentro do procedimento terá um desempenho bem melhor conforme a massa de dados vai crescendo.

 

Abraços

 

Olá Daniel! primeiramente Obrigado pelo apoio.

Agora que vi que o XML foi sem as tags. Mas o exemplo é como vc citou mesmo, desse jeitinho.

 

Mas não entendi uma coisa, vc diz se tiver 10 voltas seria 10 campos de voltas? Porque eu não queria isso, até porque o Nr de Lap é variável. Eu quero 1 para cada lap, no caso do exemplo 2 registros.

usando o xml que vc citou o resultado na tabela ficaria assim:


Nome Lap

Diego Jacometti 108.6030

Diego Jacometti 107.8197

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa Tarde

 

Não, a ideia do código que fiz foi exatamente abstrair a questão das voltas, se liga no outro exemplo abaixo

 


declare @x xml ='<dados>
<Name>Diego Jacometti</Name>
<lap>108.6030</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
<lap>107.8197</lap>
</dados>'
 
 
select 
	 tb.fd.value('../Name[1]', 'varchar(50)')
	,tb.fd.value('.', 'varchar(50)')
from @x.nodes('dados/lap') tb(fd)

 

Explicando o bloco abaixo serve para pegar o valor do nó pai

 

 tb.fd.value('../Name[1]', 'varchar(50)')

 

Qualquer coisa é só perguntar

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Daniel,

acho que o problema dele esta na tag LAP que pode variar de acordo com a tag LAPS.

Eu tentei fazer um exemplo de como dividir as tag LAP de acordo com o parametro do LAPS, mas estou sem ambiente esta semana.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.