2009-04-08 12 views
4

Ich habe zwei Tabellen. Eine davon ist einfacher String/ID nachschlagen:SQL Update mit einem Join?

StrTable:

 
str_key String 
0  'a' 
1  'b' 

wo die Saiten einzigartig sind. Der andere ist komplexer und umfasst den gemeinsamen string_id

ValTable:

 
str_key other_key val 
0  0  1.234 
0  1  1.567 
1  0  1.890 

Jetzt möchte ich mich auf ValTable ein Update tun, eine Zeichenfolge verwendet, die ich Lookup die str_key über StrTable zu bekommen. Die einfache Aktualisierung wäre:

UPDATE ValTable SET val = 2.124 WHERE str_key = 0 AND other_key = 1 LIMIT 1 
IF @@ROWCOUNT=0 INSERT INTO ValTable VALUES (0,1,2.124); 

So wie kann ich ändern dies die str_key mit einigen Zeichenfolge ‚a‘ aufzublicken aufzunehmen? Ich nehme an, dass ich einen Join brauche, aber ich habe noch nie ein Update beigesteuert. Oder kann ich meiner where-Klausel einfach mehr hinzufügen?

+0

Du hast nicht die DDL haben für Ihre Tabellen, aber das str_key unter der Annahme und other_key die PK für Ihre ValTable bilden, gibt es einen Grund, dass Sie die „LIMIT 1“ haben? Selbst wenn es nicht die PK ist, scheint es seltsam zu sein, LIMIT hier zu verwenden. –

+0

Ich war mir nicht sicher, ob es einen Sweep der gesamten Tabelle ohne die Begrenzung dort geben würde, aber ich nehme an, es ist klug genug zu wissen, dass der Compound-Schlüssel ist * die * -Taste und betrifft nur diese eine Zeile. –

Antwort

14

Dies ist die Syntax, die Sie brauchen:

UPDATE v 
SET  val = 2.124 
FROM ValTable v 
     INNER JOIN 
       StringTable s 
       ON v.str_key = s.str_key 
WHERE s.String = 'a' 
AND  v.other_key = 1 

IF @@ROWCOUNT = 0 
BEGIN 

     INSERT 
     INTO ValTable 
     SELECT str_key, 1, 2.124 
     FROM StringTable 
     WHERE String = 'a' 

END 
+0

Wie ändere ich die zweite Zeile? Kann ich das einfach tun: IF @@ ROWCOUNT = 0 INSERT IN V WERTE (v.str_key, 1, 2.124) Oder muss ich v.str_key mit einem anderen Join erneut bestimmen? –

1

Das obige Beispiel von David M gültig ist und funktioniert. Abhängig von der Größe Ihrer Tabelle sollten Sie "Blind Updates" vermeiden, da dies bei sehr großen Tabellen zu Performance-Problemen führen kann. Beachten Sie die Tabellenhinweise in IF EXISTS().

IF EXISTS(
     SELECT 
      * 
     FROM 
      ValTable v WITH(NOLOCK) 
      INNER JOIN StringTable s WITH(NOLOCK) ON v.str_key = s.str_key 
     WHERE 
      s.String = 'a' 
     AND v.other_key = 1 
    ) 
BEGIN 
    UPDATE 
     v 
    SET  
     val = 2.124 
    FROM  
     ValTable v 
     INNER JOIN StringTable s ON v.str_key = s.str_key 
    WHERE 
     s.String = 'a' 
    AND v.other_key = 1 
END 
ELSE 
BEGIN 
    INSERT INTO ValTable 
     --(You should define your columns here, You didn't provide a sample schema so I don't know what your columns are.) 
     --(Col1,COl2,COl3,etc...) 
    SELECT 
     str_key, 1, 2.124 
    FROM  
     StringTable 
    WHERE 
     String = 'a' 
END