14. marts 2006 - 13:43
Der er
22 kommentarer og 1 løsning
Stored procedure: split af en streng
Jeg ved det kan lade sig gøre, jeg har nemlig gjort det før, men jeg kan bare ikke huske syntaksen. Jeg kalder en st. proc med et sæt af argumenter. Det ene argument er en lang ';'-separeret streng. Jeg ønsker at splitte denne streng på ';', og for hver element udføre en SQL Insert, hvori elementet indgår i min SQL. Er der en der har et eksempel?
Annonceindlæg fra Infor
ij
Nybegynder
14. marts 2006 - 14:12
#1
Yes se om det her er noget du kan bruge: REATE PROCEDURE USPSplitPersonKeys @list ntext, @delimiter char(1) = N',' AS DECLARE @pos int, @textpos int, @chunklen smallint, @tmpstr nvarchar(4000), @leftover nvarchar(4000), @tmpval int, @sql nvarchar(4000) SET NOCOUNT ON SELECT @textpos = 1, @leftover = '' WHILE @textpos <= datalength(@list) / 2 BEGIN SELECT @chunklen = 4000 - datalength(@leftover) / 2 SELECT @tmpstr = @leftover + substring(@list, @textpos, @chunklen) SELECT @textpos = @textpos + @chunklen SELECT @pos = charindex(@delimiter, @tmpstr) WHILE @pos > 0 BEGIN SELECT @tmpval = cast(left(@tmpstr, @pos - 1) as int) SELECT @tmpval = ltrim(rtrim(@tmpval)) if (@tmpval <> 0) BEGIN INSERT #personkeys(PK) VALUES (@tmpval) END SELECT @tmpstr = substring(@tmpstr, @pos + 1, len(@tmpstr)) SELECT @pos = charindex(@delimiter, @tmpstr) END SELECT @leftover = @tmpstr END if (@leftover <> 0) BEGIN INSERT #personkeys(PK) VALUES(cast(ltrim(rtrim(@leftover)) as int)) END GO
ij
Nybegynder
14. marts 2006 - 14:15
#2
ja OK mangler lige et "C" i CREATE PROCEDURE, men den har du nok luret :-)
14. marts 2006 - 14:16
#3
DECLARE @Position int IF RIGHT( RTRIM( @InputString ), 1 ) <> ';' SET @InputString = @InputString + ';' SET @Position = PATINDEX( '%;%', @InputString ) WHILE @Postition <> 0 BEGIN 'Your stuff END Her kører en løkke en gang for hver element der er i input strengen, splittet med ;
14. marts 2006 - 14:16
#4
øv, der var du hurtigere...
14. marts 2006 - 14:28
#5
Ok, -> dj_uncas dit ekempel ser meget kort ud. Hvis min streng fx. hedder @stringOfID (indeholder: "1;2;3;445;45;") Hvordan ser loopet ud, hvori der fx står: INSERT INTO aTABLE(FK_IDNR) VALUES(???) <- herinde skal min ID'er indgå pr loop Hvordan ser det så ud?
14. marts 2006 - 14:39
#6
-> dj_uncas, hvor laver du denne? IF RIGHT( RTRIM( @brandIDs ), 1 ) <> ';'
14. marts 2006 - 14:45
#7
istedet for hvor, skal der stå hvofor.
14. marts 2006 - 15:10
#8
Den første linje tjekke om der er ; i slutningen af @InputString, da while-løkken er bundet op på antallet af ;'er i den.. Inde i løkken skal du have dette: SET @ID = LEFT( @InputString, @Position - 1 ) INSERT INTO aTABLE(FK_IDNR) VALUES(@ID) SET @InputString = STUFF( @InputString, 1, @Position ) SET @Position = PATINDEX( '%;%', @InputString )
14. marts 2006 - 15:25
#9
stuff funktionen kræver 4 argumenter, hvad er den fjerde?
14. marts 2006 - 15:28
#10
Der er altid et ';' til sidst, så den linje har jeg fjernet. Jeg tror at jeg er tæt på, men stuff funktionen kræver 4 argumenter. Min kode ser således ud: SET @brandIDs = @brandIDs + ';' SET @position = PATINDEX( '%;%', @brandIDs ) WHILE @position <> 0 BEGIN SET @brandID = LEFT( @brandIDs, @position - 1 ) INSERT INTO BrandInitiative(FK_BrandID, FK_InitiativeID) VALUES(@brandID,@newID) SET @brandIDs = STUFF( @brandIDs, 1, @Position ) SET @Position = PATINDEX( '%;%', @brandIDs ) END ------- Jeg tror, der er noget galt....
14. marts 2006 - 15:42
#11
Der er desværre gået kage i eksemplet. Kan du skrive eksemplet igen bare med: @brandIDs (indeholder: "1;2;3;445;45;") SET @position = PATINDEX( '%;%', @brandIDs ) WHILE @position <> 0 BEGIN SET @brandID = LEFT( @brandIDs, @position - 1 ) INSERT INTO Brand(BrandID) VALUES(@brandID) SET @brandIDs = STUFF( @brandIDs, 1, @Position ) SET @Position = PATINDEX( '%;%', @brandIDs ) END Det her virker ikke! Hvad mangler jeg????
14. marts 2006 - 15:42
#12
STUFF problemet er der stadigvæk.
14. marts 2006 - 15:50
#14
Men der er jo noget galt, jeg ved jo ikke hvor lange mine ID'er er. Det der mangler i STUFF er længden af det jeg vil stuffe, men den kender jeg jo ikke.
14. marts 2006 - 15:50
#15
Hmm, ok den kan være tom prøver lige...
14. marts 2006 - 15:55
#16
Den laver et endless loop....
14. marts 2006 - 16:01
#17
Hmmm.. brb.. Det ved jeg ikke rigtig.. Det her: ---------------------------------------- SET @position = PATINDEX( '%;%', @brandIDs ) WHILE @position <> 0 BEGIN SET @brandID = LEFT( @brandIDs, @position - 1 ) --INSERT INTO Brand(BrandID) VALUES(@brandID) PRINT @brandID SET @brandIDs = STUFF( @brandIDs, 1, @Position, '' ) SET @Position = PATINDEX( '%;%', @brandIDs ) END ---------------------------------------- virker fint hos mig
14. marts 2006 - 16:02
#18
bare fjern kommentar fra INSERT (--) og fjern PRINT linjen, så skulle den være god. Ellers er jeg nødt til at se hele din kode.
14. marts 2006 - 16:09
#19
Det virker også hos mig nu....Det er min transaktions styring, der er noget galt i. Kan du se, hvad der er galt? BEGIN TRANSACTION INSERT INTO dbo.Initiative(FK_ProductGroupID, FK_CountryID, [Name], CommercialName) VALUES(@productGroupID, @countryID, @productName, @commercialName) IF (@@ERROR <> 0) GOTO onError SELECT @newID = @@IDENTITY IF (@@ERROR <> 0) GOTO onError SET @position = PATINDEX( '%;%', @brandIDs ) WHILE @position <> 0 BEGIN SET @brandID = LEFT( @brandIDs, @position - 1 ) INSERT INTO Brand(BrandID) VALUES(@brandID) IF (@@ERROR <> 0) GOTO onError SET @brandIDs = STUFF( @brandIDs, 1, @Position, '' ) SET @Position = PATINDEX( '%;%', @brandIDs ) END COMMIT TRANSACTION RETURN(0) onError: ROLLBACK TRANSACTION RETURN(1)
14. marts 2006 - 16:32
#20
Tja, du når ned til din onError lige meget hvad der ellers sker i resten af sql'en...
14. marts 2006 - 20:28
#21
Okay, men så skal der jo ændringer i min transaktionelle stored proc. Men i eksemplet i en bog, stod det ellers på denne måde.
15. marts 2006 - 08:11
#22
dj_juncas smid et svar ind, så du kan få points
15. marts 2006 - 10:06
#23
ok, det kommer her.
Computerworld tilbyder specialiserede kurser i database-management