sql >> Database >  >> RDS >> Sqlserver

SQL-draaitabel is alleen-lezen en cellen kunnen niet worden bewerkt?

Ervan uitgaande dat u een unieke beperking heeft op n_id, field wat betekent dat er maximaal één rij kan overeenkomen, kun je (in theorie tenminste) een INSTEAD OF gebruiken trekker.

Dit zou gemakkelijker zijn met MERGE (maar dat is niet beschikbaar tot SQL Server 2008) omdat u UPDATES moet behandelen van bestaande gegevens, INSERTS (Waar een NULL waarde is ingesteld op NON NULL one) en DELETES waarbij een NON NULL waarde is ingesteld op NULL .

Een ding dat u hier zou moeten overwegen, is hoe u omgaat met UPDATES die alle kolommen op een rij instelt op NULL Ik deed dit tijdens het testen van de onderstaande code en was een minuut of twee behoorlijk in de war totdat ik me realiseerde dat dit alle rijen in de basistabel voor een n_id had verwijderd (wat betekende dat de operatie niet omkeerbaar was via een andere UPDATE uitspraak). Dit probleem kan worden vermeden door de VIEW-definitie OUTER JOIN . te gebruiken op welke tafel dan ook n_id is de PK van.

Een voorbeeld van het soort ding staat hieronder. U moet ook rekening houden met mogelijke race-omstandigheden in de INSERT /DELETE code aangegeven en of je daar wat extra vergrendelingstips nodig hebt.

CREATE TRIGGER trig
ON pivoted
INSTEAD OF UPDATE
AS
  BEGIN
      SET nocount ON;

      DECLARE @unpivoted TABLE (
        n_id             INT,
        field            VARCHAR(10),
        c_metadata_value VARCHAR(10))

      INSERT INTO @unpivoted
      SELECT *
      FROM   inserted UNPIVOT (data FOR col IN (fid, sid, NUMBER) ) AS unpvt
      WHERE  data IS NOT NULL

      UPDATE m
      SET    m.c_metadata_value = u.c_metadata_value
      FROM   metadata m
             JOIN @unpivoted u
               ON u.n_id = m.n_id
                  AND u.c_metadata_value = m.field;

      /*You need to consider race conditions below*/
      DELETE FROM metadata
      WHERE  NOT EXISTS(SELECT *
                        FROM   @unpivoted u
                        WHERE  metadata.n_id = u.n_id
                               AND u.field = metadata.field)

      INSERT INTO metadata
      SELECT u.n_id,
             u.field,
             u.c_metadata_value
      FROM   @unpivoted u
      WHERE  NOT EXISTS (SELECT *
                         FROM   metadata m
                         WHERE  m.n_id = u.n_id
                                AND u.field = m.field)
  END  


  1. Laravel:dynamisch verbinding maken met databases

  2. Instellingen van verbindingstime-out voor Oracle-database

  3. Hoe InterfaceError op te lossen:2003:Kan geen verbinding maken met MySQL-server op '127.0.0.1:3306:3306' (11001 getaddrinfo mislukt)

  4. Waarom selecteren sommige mysql-verbindingen oude gegevens in de mysql-database na een delete + insert?