webForumDet fria alternativet

Return multiple value?

26 svar · 3 122 visningar · startad av harry_boy

harry_boyMedlem sedan feb. 2003199 inlägg
#1

Jag försöker skapa följande trigger:

CREATE TRIGGER [dbo].[FreightSearch] 
ON [dbo].[Ord]
FOR UPDATE
AS

BEGIN 
  SET NOCOUNT ON;

UPDATE Ord
SET Web = (SELECT CONCAT(Stc.Ad4, Ord.OrdNo) AS Freight_Search FROM Ord INNER JOIN Stc ON Ord.OrdNo = Ord.OrdNo)
        
END  
GO

Men jag får felmeddelande att jag försöker sätta in "multiple value". Någon som ser vad jag gör för nybörjarfel?

nitro2k01Medlem sedan aug. 20037 630 inlägg
#2
ON Ord.OrdNo = Ord.OrdNo

Detta gör att alla rader väljs ur tabellen. Du måste använda unika namn för tabellnamnen. Du kan åstadkomma detta med ett alias, som du kan skapa med AS även för tabellnamn.

UPDATE Ord
SET Web = (SELECT CONCAT(Stc.Ad4, Ord.OrdNo) AS Freight_Search FROM [u]Ord AS Ord2[/u] INNER JOIN Stc ON [u]Ord.OrdNo = Ord2.OrdNo[/u])

(Inga garantier att koden i övrigt är korrekt.)

Sen borde du kunna göra detta med en UPDATE+JOIN utan inre select, men det är en annan femma.

harry_boyMedlem sedan feb. 2003199 inlägg
#3

Hejsan och tack nitro2k01.

Jag fick tyvärr samma problem.

"... returned more than 1 value. This is permitted when the subquery follows ....."

Hur skulle update+join kunna se ut? Jag adderar ju värden från två olika kolumner till kolumnen web. Och jag vill ju att ordno ska tas från den ordern jag står på.

@ndersMedlem sedan juni 200026 914 inlägg
#4

Hur hänger tabellerna Stc och Ord ihop? Ordno?
Måste du verkligen joina?

UPDATE Ord
SET Web = 
      (SELECT CONCAT(Ad4, inserted.Ordno) FROM Stc WHERE Ordno = inserted.Ordno)
WHERE Ordno = inserted.Ordno

Och slutligen kanske du ska fundera på om det är rätt ställe att konkatenera på - kanske ska du göra det i presentationen istället?

mvh

nitro2k01Medlem sedan aug. 20037 630 inlägg
#5

Vänta nu, du har ju inget villkor på Stc, så du joinar alla rader i den tabellen! Menade du kanske Stc.OrdNo = Ord.OrdNo? Eller förresten efter lite googlande verkar det som du måste använda dig av nyckelordet INSERTED för att få reda på vad som har uppdaterats.
Efter samma googlande tror jag även att du ska ha AFTER UPDATE istället för FOR UPDATE.

Prova:

CREATE TRIGGER [dbo].[FreightSearch] 
ON [dbo].[Ord]
AFTER UPDATE
AS

BEGIN 
  SET NOCOUNT ON;

UPDATE Ord
SET Web = CONCAT(Stc.Ad4, Ord.OrdNo) 
WHERE inserted.OrdNo = Ord.OrdNo
INNER JOIN Stc ON Stc.OrdNo = Ord.OrdNo

END  
GO

Jag skriver denna kod utan att kunna testa den och utan att egentligen veta sen innan hur saker funkar i MS SQL, men förhoppningsvis kommer det att gå att få koden att funka till slut. :)

harry_boyMedlem sedan feb. 2003199 inlägg
#6

Det är min okunskap som lyser igenom. Det är naturligtvis Ord.FrStc som ska vara samma som Stc.FrStc.

Hur menar du "Och slutligen kanske du ska fundera på om det är rätt ställe att konkatenera på - kanske ska du göra det i presentationen istället?"?

@ndersMedlem sedan juni 200026 914 inlägg
#7

Det jag menar är: Någonstans visar du datat, antar jag. Kanske är det bättre att göra konkateneringen / joinen där, istället för att lagra ett färdigkonkatenerat värde. Jag säger inte att det är rätt - jag vet ju ingenting om ditt system - men jag bara säger att du kan fundera på det. :)

harry_boyMedlem sedan feb. 2003199 inlägg
#8

Ok jag förstår.

Jag måste lagra datat på detta sätt då jag inte kan påverka hur det ska visas..

@ndersMedlem sedan juni 200026 914 inlägg
#9

Dåså, då är det rätt approach. :-)

Det finns flera sätt att göra en dylik update på - kanske hade jag valt att göra så här:

DECLARE @Web VARCHAR(50)

SELECT @Web = CONCAT(Stc.Ad4, Ord.OrdNo) 
FROM Stc 
INNER JOIN Ord 
   ON St.FrStc = Ord.FrStc
WHERE Ord.OrdNo = inserted.OrdNo

UPDATE Ord SET Web = @Web WHERE OrdNo = inserted.OrdNo

mvh

harry_boyMedlem sedan feb. 2003199 inlägg
#10

När jag kör detta så får jag

Msg 4104, Level 16, State 1, Procedure FreightSearch, Line 17
The multi-part identifier "insterted.OrdNo" could not be bound.

Och rad 17 är

rad 2 i nedan
UPDATE Ord SET Web = @Web
WHERE OrdNo = insterted.OrdNo

harry_boyMedlem sedan feb. 2003199 inlägg
#11

Ord.OrdNo är primärnyckel och int, not null
Ord.Web är varchar(260), not null
Stc.StcNo är primär, int, not null
Stc.Ad4 är varchar(60), not null

har det något med skillnaden i datatyp att göra?

Jag ser också att jag stavade fel till inserted och skrev insterted men det kvittade när jag ändade jag fick samma fel.

harry_boyMedlem sedan feb. 2003199 inlägg
#12

Jag uppdaterade till följande:

UPDATE Ord SET Web = @Web FROM inserted
WHERE Ord.OrdNo = Inserted.OrdNo

Och då fungerar det och den uppdaterar enbart den raden man sparar om. Men problemet är att i inserted verkar ligga det ett statiskt värde sedan tidigare (talet 282, från en tidigare order). Nu när jag sparar en annan order så får den samma rad. Dvs ad4 samt ordernr282 vilket är fel. Jag vill ju att den ska få det ordernr som kommer från den raden som sparas.

harry_boyMedlem sedan feb. 2003199 inlägg
#13

Så här ser nu koden ut:

CREATE TRIGGER [dbo].[FreightSearch] 
ON [DB1].[dbo].[Ord]
AFTER UPDATE
AS

BEGIN 
  SET NOCOUNT ON;

DECLARE @Web VARCHAR(260)

SELECT @Web = CONCAT(Stc.Ad4, Ord.OrdNo) 
FROM Stc 
INNER JOIN Ord 
   ON Stc.StcNo = Ord.FrStc

UPDATE Ord SET Web = @Web FROM inserted
WHERE  Ord.OrdNo = inserted.OrdNo
   
END  
GO

Och sparar jag en ny order så blir det rätt. Men sparar jag om en gammal så ersätts "OrdNo" med den senast nya order.

Vad är fel som gör att jag inte får med mig ordno från aktuella ordern jag uppdaterar eller sparar?

harry_boyMedlem sedan feb. 2003199 inlägg
#14

Snälla rara är det ingen som kan hjälpa mig med vad jag eventuellt gör för fel.

Jättetack på förhand.

nitro2k01Medlem sedan aug. 20037 630 inlägg
#15

I select-satsen så har du inget som knyter ihop ordern med det id som just har lagts in. Prova:

CREATE TRIGGER [dbo].[FreightSearch] 
ON [DB1].[dbo].[Ord]
AFTER UPDATE
AS

BEGIN 
  SET NOCOUNT ON;

DECLARE @Web VARCHAR(260)

SELECT @Web = CONCAT(Stc.Ad4, inserted.OrdNo) 
FROM Stc 
WHERE Stc.StcNo = inserted.FrStc

UPDATE Ord SET Web = @Web FROM inserted
WHERE  Ord.OrdNo = inserted.OrdNo
   
END  
GO
harry_boyMedlem sedan feb. 2003199 inlägg
#16

Tack nitro2k01 men fick tyvärr följande fel

Msg 4104, Level 16, State 1, Procedure FreightSearch, Line 13
The multi-part identifier "inserted.FrStc" could not be bound.
Msg 4104, Level 16, State 1, Procedure FreightSearch, Line 11
The multi-part identifier "inserted.OrdNo" could not be bound.

harry_boyMedlem sedan feb. 2003199 inlägg
#17

Jag har fått allt att fungera nu i min demo-miljö men när jag skulle använda den på en annan installation så säger den att CONCAT inte fungerar i SQL 2008 :-( Felmeddelandet är enligt följande:

'CONCAT' is not a recognized built-in function name.

CREATE TRIGGER [dbo].[FreightSearch] 
ON [DB1].[dbo].[Ord]

AFTER UPDATE
AS

BEGIN 
  SET NOCOUNT ON;

DECLARE @Web VARCHAR(260)

SELECT @Web = CONCAT(Stc.Ad4, inserted.OrdNo) 
FROM Stc 
JOIN inserted
ON Stc.StcNo = inserted.FrStc

UPDATE Ord SET Web = @Web FROM inserted
WHERE  Ord.OrdNo = inserted.OrdNo
AND Ord.TrTp = '1'
   
END  
GO

Jag som blev så glad att det fungerar. Men hur gör jag för att skriva om det till SQL 2008

@ndersMedlem sedan juni 200026 914 inlägg
#18

Prova att bara konkatenera med +.

Stc.Ad4 + Convert(nvarchar(10), inserted.OrdNo)
harry_boyMedlem sedan feb. 2003199 inlägg
#19

Gör jag det så får jag

Msg 156, Level 15, State 1, Procedure FreightSearch, Line 20
Incorrect syntax near the keyword 'FROM'.

Och koden ser ut

SELECT @WebPg = CONCAT(Stc.Ad4 + Convert(nvarchar(10), inserted.OrdNo) 
FROM Stc 
JOIN inserted
ON Stc.StcNo = inserted.FrStc
@ndersMedlem sedan juni 200026 914 inlägg
#20

Nej, bort med concat alltså. Så här tänkte jag:

SELECT @WebPg = Stc.Ad4 + Convert(nvarchar(10), inserted.OrdNo) 
FROM Stc 
JOIN inserted
ON Stc.StcNo = inserted.FrStc

mvh

125 ms totalt · 3 externa anrop · cache AV · v20260731051352-full.56cc9887
0 ms — hämta statistik (cache)
0 ms — hämta forumlista (cache)
123 ms — hämta tråd, inlägg och bilagor (db)