Frage

Ich brauche einen Datensatz in einer Datenbank mit den folgenden Feldern aktualisieren

[ID] int (AutoIncr. PK)
[ScorerID] int
[Score] int
[DateCreated] smalldatetime

Wenn ein Datensatz für den heutigen Tag existiert (nur der Datumsteil überprüft werden soll, ist nicht die Zeit) und einem gegebenen scorer, würde Ich mag den Score-Wert für diesen Kerl zu aktualisieren und zu diesem Tag. Wenn der traf keine Aufzeichnung für heute, ich möchte ein neues erstellen.

Ich bekomme graue Haare Figur versuchen, wie diese in einem einzigen setzen (ist das möglich?) SQL-Anweisung. Durch die Art und Weise bin ich mit einer MSSQL-Datenbank und die ExecuteNonQuery() Methode, um die Abfrage zu erteilen.

War es hilfreich?

Lösung

IF EXISTS (SELECT NULL FROM MyTable WHERE ScorerID = @Blah AND CONVERT(VARCHAR, DateCreated, 101) = CONVERT(VARCHAR, GETDATE(), 101))
    UPDATE MyTable SET blah blah blah
ELSE
    INSERT INTO MyTable blah blah blah

Andere Tipps

Die anderen Jungs haben 2005 (und vor) kompatibel T-SQL / apprroaches bedeckt. Ich wollte nur hinzufügen, dass, wenn Sie Glück haben, mit SQL Server zu arbeiten, 2008, können Sie die Vorteile des neuen Merge nehmen können (manchmal als Upsert) Erklärung.

hatte ich Probleme bei der Suche einen Blog-Eintrag oder Gegenstände, die es weiter erklärt, aber ich habe diese eher (1) hilfreich Eintrag . Der offizielle MSDN Eintrag (2) hier.

(1) [ http: // www.sqlservercurry.com/2008/05/sql-server-2008-merge-statement.html]
(2) [ http://msdn.microsoft.com/ en-us / library / bb510625.aspx]

CREATE PROCEDURE InsertOrUpdateScorer(@ScorerID INT, @Score INT)
AS
BEGIN
  IF EXISTS (
    SELECT 1 
    FROM Scorer 
    WHERE ScorerID = @ScorerID AND DATEDIFF(dd, GETDATE(), DateCreated) = 0
  )
  BEGIN
    UPDATE
      Scorer
    SET 
      Score = @Score
    WHERE
      ScorerID = @ScorerID

    RETURN @ScorerID
  END
  ELSE
  BEGIN
    INSERT 
      Scorer 
      (ScorerID, Score, DateCreated)
    VALUES
      (@ScorerID, @Score, GETDATE())

    RETURN SCOPE_IDENTITY()
  END
END

Mit dem Rückgabewert der Prozedur die neue ScorerId greifen.

SqlCommand UpdateScorer = New SqlCommand("InsertOrUpdateScorer", DbConn);
UpdateScorer.CommandType = CommandType.StoredProcedure;

SqlParameter RetValue = UpdateScorer.Parameters.Add("RetValue", SqlDbType.Int);
RetValue.Direction = ParameterDirection.ReturnValue;

SqlParameter Score = UpdateScorer.Parameters.Add("@Score", SqlDbType.Int);
Score.Direction = ParameterDirection.Input;

SqlParameter ScorerId = UpdateScorer.Parameters.Add("@ScorerID", SqlDbType.Int);
ScorerId.Direction = ParameterDirection.Input;

Score.Value = 15;    // whatever
ScorerId.Value = 15; // whatever

UpdateScorer.ExecuteNonQuery();
Console.WriteLine(RetValue.Value);

Für Fall, wenn gewünscht wird, zu aktualisieren oder alle Werte auf einmal einsetzen, nicht nur für einen Datensatz verwenden ich diesen Schnipsel

1. Führen Sie den Update-Skript

UPDATE Table1 
SET OPIS = T1.OPIS
FROM
    Table1 AS T
INNER JOIN
    Table2 AS T1
    ON
        T.col = T1.col;

Dann das Insert script

INSERT INTO Table1 
SELECT * FROM 
    (
        SELECT T1.* Table2 AS T1
        LEFT JOIN Table1 AS T2 ON (T2.col = T1.col)
        WHERE T2.col IS NULL
    ) AS T;

Ich hoffe, dass jemand das nützlich gefunden.

Das Äquivalent von dieser in MySql (in einigen Fällen) ist so etwas wie folgt aus:

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

kann jemand herausgefunden, dass diese zu dem Artikel unter Lösungen verwendet ist für INSERT oder UPDATE auf SQL Server

Aktualisierte Version mit MERGE (Transact-SQL) :

DECLARE @USER_ID AS INT=76;
DECLARE @TYPE AS NVARCHAR(MAX)='set.global';
DECLARE @FKEY AS NVARCHAR(MAX)='21';
DECLARE @DATA AS NVARCHAR(MAX)='test';

        begin tran
            MERGE UserData
            USING (SELECT @USER_ID, @TYPE, @FKEY, @DATA) AS Source([UserId], [Type], [FKey], [Data])
            ON (UserData.[UserId] = Source.[UserId] AND UserData.[Type] = Source.[Type] AND (UserData.[FKey] = Source.[FKey] OR (Source.[FKey] IS NULL AND UserData.[FKey] IS NULL)))
            WHEN MATCHED
            THEN
                UPDATE SET [Data] = Source.[Data]
            WHEN NOT MATCHED BY TARGET THEN
                INSERT 
                           ([UserId]
                           ,[Type]
                           ,[FKey]
                           ,[Data])
                     VALUES
                           ( Source.[UserId]
                           ,Source.[Type]
                           ,Source.[FKey]
                           ,Source.[Data]);

        commit tran
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top