Ich habe eine Anweisung, die ich verwende, um eine Datenzeile hinzuzufügen oder zu aktualisieren. Ich beobachte das SQL, das eine Reihe aktualisiert, wenn keine offensichtlichen Änderungen vorhanden sind. Ich versuche herauszufinden, warum es darauf ankommt, die Zeile zu aktualisieren, wenn das SQL es verhindern sollte.Warum aktualisiert SQL einige Zeilen, wenn keine Änderungen festgestellt werden?
Ich aktualisiere etwa 1.000 Zeilen auf diese Weise (eine nach der anderen) und nur 2 Zeilen scheinen zu aktualisieren, wenn die Maske, die ich erstellt habe schlägt vor, dass sie nicht sollten.
Hier ist der entsprechende SQL-Schnipsel:
...
ELSE IF NOT EXISTS (
SELECT PERMIT_STATUS, PERMIT_LOCATION, PERMIT_COMMODITY, PERMIT_TYPE_CODE, PERMIT_TYPE_DESCRIPTION, PERMIT_ALLOCATION_METHOD, PERMIT_OPERATION_NAME, OWNERS, SHARE_PERCENTAGE, OPERATOR, MINERALS, PERMIT_DURATION_YEARS, PERMIT_DURATION_MONTHS, PERMIT_AREA, PERMIT_AREA_UNIT, PERMIT_OFFSHORE_ONSHORE, PERMIT_STATUS_DATE, PERMIT_MINERAL_GROUP, PERMIT_MP, SUBSEQUENT_TO_PERMIT, PERMIT_COMMENCEMENT_DATE, PERMIT_EXPIRY_DATE, PERMIT_GRANT_DATE, PERMIT_NONEXCLUSIVE_YN, ShapeGeoJson, Removed
FROM MyTable
WHERE PERMIT_NUMBER = @PERMIT_NUMBER
INTERSECT
SELECT @PERMIT_STATUS, @PERMIT_LOCATION, @PERMIT_COMMODITY, @PERMIT_TYPE_CODE, @PERMIT_TYPE_DESCRIPTION, @PERMIT_ALLOCATION_METHOD, @PERMIT_OPERATION_NAME, @OWNERS, @SHARE_PERCENTAGE, @OPERATOR, @MINERALS, @PERMIT_DURATION_YEARS, @PERMIT_DURATION_MONTHS, @PERMIT_AREA, @PERMIT_AREA_UNIT, @PERMIT_OFFSHORE_ONSHORE, @PERMIT_STATUS_DATE, @PERMIT_MINERAL_GROUP, @PERMIT_MP, @SUBSEQUENT_TO_PERMIT, @PERMIT_COMMENCEMENT_DATE, @PERMIT_EXPIRY_DATE, @PERMIT_GRANT_DATE, @PERMIT_NONEXCLUSIVE_YN, @ShapeGeoJson, @Removed
)
BEGIN
UPDATE MyTable
SET PERMIT_STATUS = @PERMIT_STATUS
,PERMIT_LOCATION = @PERMIT_LOCATION
,PERMIT_COMMODITY = @PERMIT_COMMODITY
,PERMIT_TYPE_CODE = @PERMIT_TYPE_CODE
,PERMIT_TYPE_DESCRIPTION = @PERMIT_TYPE_DESCRIPTION
,PERMIT_ALLOCATION_METHOD = @PERMIT_ALLOCATION_METHOD
,PERMIT_OPERATION_NAME = @PERMIT_OPERATION_NAME
,OWNERS = @OWNERS
,SHARE_PERCENTAGE = @SHARE_PERCENTAGE
,OPERATOR = @OPERATOR
,MINERALS = @MINERALS
,PERMIT_DURATION_YEARS = @PERMIT_DURATION_YEARS
,PERMIT_DURATION_MONTHS = @PERMIT_DURATION_MONTHS
,PERMIT_AREA = @PERMIT_AREA
,PERMIT_AREA_UNIT = @PERMIT_AREA_UNIT
,PERMIT_OFFSHORE_ONSHORE = @PERMIT_OFFSHORE_ONSHORE
,PERMIT_STATUS_DATE = @PERMIT_STATUS_DATE
,PERMIT_MINERAL_GROUP = @PERMIT_MINERAL_GROUP
,PERMIT_MP = @PERMIT_MP
,SUBSEQUENT_TO_PERMIT = @SUBSEQUENT_TO_PERMIT
,PERMIT_COMMENCEMENT_DATE = @PERMIT_COMMENCEMENT_DATE
,PERMIT_EXPIRY_DATE = @PERMIT_EXPIRY_DATE
,PERMIT_GRANT_DATE = @PERMIT_GRANT_DATE
,PERMIT_NONEXCLUSIVE_YN = @PERMIT_NONEXCLUSIVE_YN
,ShapeGeoJson = @ShapeGeoJson
,UpdatedUtc = GETUTCDATE()
,Removed = @Removed
,UpdatedMask = (
IIF (PERMIT_STATUS != @PERMIT_STATUS, 4096, 0) +
IIF (PERMIT_LOCATION != @PERMIT_LOCATION, 256, 0) +
IIF (PERMIT_COMMODITY != @PERMIT_COMMODITY, 512, 0) +
IIF (PERMIT_TYPE_CODE != @PERMIT_TYPE_CODE, 64, 0) +
IIF (PERMIT_TYPE_DESCRIPTION != @PERMIT_TYPE_DESCRIPTION, 128, 0) +
IIF (PERMIT_ALLOCATION_METHOD != @PERMIT_ALLOCATION_METHOD, 1024, 0) +
IIF (PERMIT_OPERATION_NAME != @PERMIT_OPERATION_NAME, 2048, 0) +
IIF (OWNERS != @OWNERS, 1048576, 0) +
IIF (SHARE_PERCENTAGE != @SHARE_PERCENTAGE, 2097152, 0) +
IIF (OPERATOR != @OPERATOR, 4194304, 0) +
IIF (MINERALS != @MINERALS, 8388608, 0) +
IIF (PERMIT_DURATION_YEARS != @PERMIT_DURATION_YEARS, 32768, 0) +
IIF (PERMIT_DURATION_MONTHS != @PERMIT_DURATION_MONTHS, 65536, 0) +
IIF (PERMIT_AREA != @PERMIT_AREA, 67108864, 0) +
IIF (PERMIT_AREA_UNIT != @PERMIT_AREA_UNIT, 134217728, 0) +
IIF (PERMIT_OFFSHORE_ONSHORE != @PERMIT_OFFSHORE_ONSHORE, 262144, 0) +
IIF (PERMIT_STATUS_DATE != @PERMIT_STATUS_DATE, 8192, 0) +
IIF (PERMIT_MINERAL_GROUP != @PERMIT_MINERAL_GROUP, 131072, 0) +
IIF (PERMIT_MP != @PERMIT_MP, 524288, 0) +
IIF (SUBSEQUENT_TO_PERMIT != @SUBSEQUENT_TO_PERMIT, 33554432, 0) +
IIF (PERMIT_COMMENCEMENT_DATE != @PERMIT_COMMENCEMENT_DATE, 16, 0) +
IIF (PERMIT_EXPIRY_DATE != @PERMIT_EXPIRY_DATE, 32, 0) +
IIF (PERMIT_GRANT_DATE != @PERMIT_GRANT_DATE, 8, 0) +
IIF (PERMIT_NONEXCLUSIVE_YN != @PERMIT_NONEXCLUSIVE_YN, 16384, 0) +
IIF (ShapeGeoJson != @ShapeGeoJson, 137438953472, 0) +
IIF (Removed != @Removed, 274877906944, 0)
)
WHERE PERMIT_NUMBER = @PERMIT_NUMBER;
END
...
Ich verwende die INTERSECT
Methode an der Spitze eine Änderung in einen der Spalten von Zeilendaten zu erfassen. Dies liegt daran, dass es einfacher ist, NULL-Werte in Spalten zu vergleichen.
Und Sie können sehen, dass die UpdatedMask mit einem Wert aktualisiert wird, um anzuzeigen, welche Spalten aktualisiert wurden. Wenn das Problem auftritt, wird dies auf 0 festgelegt (und wenn ich wie erwartet arbeite, sehe ich eine korrekte AktualisierteMaske).
Ich kann keine Tippfehler oder offensichtliche Logikfehler sehen. Also frage ich mich, ob SQL Azure irgendwie dazu führen könnte, dass so viele Datensätze nacheinander mit einer großen ShapeGeoJson-Spalte aktualisiert werden?
Hier ist die Tabellendefinition, falls es sinnvoll ist:
CREATE TABLE [dbo].[MyTable](
[PERMIT_NUMBER] [varchar](30) NOT NULL,
[PERMIT_STATUS] [varchar](30) NULL,
[PERMIT_LOCATION] [varchar](4000) NULL,
[PERMIT_COMMODITY] [varchar](8) NULL,
[PERMIT_TYPE_CODE] [varchar](4000) NULL,
[PERMIT_TYPE_DESCRIPTION] [varchar](255) NULL,
[PERMIT_ALLOCATION_METHOD] [varchar](4000) NULL,
[PERMIT_OPERATION_NAME] [varchar](4000) NULL,
[OWNERS] [varchar](4000) NULL,
[SHARE_PERCENTAGE] [varchar](4000) NULL,
[OPERATOR] [varchar](220) NULL,
[MINERALS] [varchar](4000) NULL,
[PERMIT_DURATION_YEARS] [varchar](4000) NULL,
[PERMIT_DURATION_MONTHS] [varchar](4000) NULL,
[PERMIT_AREA] [varchar](4000) NULL,
[PERMIT_AREA_UNIT] [varchar](4) NULL,
[PERMIT_OFFSHORE_ONSHORE] [varchar](4000) NULL,
[PERMIT_STATUS_DATE] [date] NULL,
[PERMIT_MINERAL_GROUP] [varchar](4000) NULL,
[PERMIT_MP] [varchar](4000) NULL,
[SUBSEQUENT_TO_PERMIT] [varchar](4000) NULL,
[PERMIT_COMMENCEMENT_DATE] [date] NULL,
[PERMIT_EXPIRY_DATE] [date] NULL,
[PERMIT_GRANT_DATE] [date] NULL,
[PERMIT_NONEXCLUSIVE_YN] [char](1) NULL,
[ShapeGeoJson] [varchar](max) NOT NULL,
[CreatedUtc] [datetime] NOT NULL,
[UpdatedUtc] [datetime] NOT NULL,
[Removed] [bit] NOT NULL,
[UpdatedMask] [bigint] NULL,
CONSTRAINT [PK_MyTable_1] PRIMARY KEY CLUSTERED
(
[PERMIT_NUMBER] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Irgendwelche Ideen?
Der Update-Prozess läuft jeden Abend, also behalte ich die Zeilen im Auge, die meine Regeln zu durchbrechen scheinen, um zu sehen, ob da ein Muster ist. Ich habe das schon ein paar Mal gesehen, aber ich habe es versäumt, die Daten für frühere Untersuchungen zu bewahren.
diese Art von Code sehen gibt mir Albträume. Ich würde vorschlagen, ein ORM zu verwenden. –
@MrAnderson - Ich benutze Dapper, aber weil ich nicht jedes Mal einen riesigen ShapeGeoJson zurückholen möchte, um einfach zu vergleichen, dachte ich mir, ich könnte SQL Azure DTU speichern den Hinzufügen/Aktualisieren Prozess in einem Einzelruf. Aber ja, nicht das eleganteste SQL als Ergebnis. – Gavin
Bitte lesen [this] (http://spaghettiba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/) für einige Tipps zur Verbesserung Ihrer Frage. – HABO