4 Stimmen

Hilfe bei SQL Server Trigger zum Abschneiden von schlechten Daten vor dem Einfügen

Wir nutzen einen Webdienst, der beschlossen hat, die maximale Länge eines Feldes von 255 zu ändern. Wir haben eine alte Lieferantentabelle auf unserer Seite, die immer noch auf 255 begrenzt ist. Wir hoffen, dieses Problem vorübergehend mit einem Trigger lösen zu können, bis wir in unserer nächsten Iteration eine geschäftsfreundlichere Lösung implementieren können.

Damit habe ich angefangen:

CREATE TRIGGER [mySchema].[TruncDescription] 
ON  [mySchema].[myTable] 
INSTEAD OF INSERT
AS 
BEGIN
SET NOCOUNT ON;

INSERT INTO [mySchema].[myTable]
SELECT SubType, type, substring(description, 1, 255)
FROM inserted
END

Wenn ich jedoch versuche, auf myTable erhalte ich die Fehlermeldung:

Zeichenkette oder binäre Daten w abgeschnitten. Die Anweisung wurde abgebrochen.

Ich habe experimentiert mit SET ANSI_WARNINGS OFF wodurch die Abfrage zwar funktionierte, aber einfach keine Daten in die Beschreibungsspalte eingefügt wurden.

Gibt es eine Möglichkeit, einen Trigger zu verwenden, um die zu langen Daten abzuschneiden, oder gibt es eine andere Alternative, die ich verwenden kann, bis eine eloquentere Lösung entworfen werden kann? Wir sind in Bezug auf Tabellenänderungen ziemlich eingeschränkt (d. h. wir können es nicht), da es sich um eine Herstellertabelle handelt, und wir haben keine Kontrolle über den Webdienst, den wir nutzen, sodass wir ihn auch nicht bitten können, das Problem zu beheben. Für jede Hilfe wären wir dankbar.

4voto

Darryl Peterson Punkte 2200

Der Fehler kann nicht vermieden werden, da der Fehler auftritt, wenn die eingefügte Tabelle aufgefüllt wird.

Aus der Dokumentation: http://msdn.microsoft.com/en-us/library/ms191300.aspx

"Das Format der eingefügten und gelöschten Tabellen entspricht dem Format der Tabelle, für die der INSTEAD OF-Trigger definiert ist. Jede Spalte in den eingefügten und gelöschten Tabellen entspricht direkt einer Spalte in der Basistabelle."

Die einzige wirklich "clevere" Idee, die mir einfällt, ist die Nutzung von Schemata und des von einer Anmeldung verwendeten Standardschemas. Wenn Sie die Anmeldung, die der Webdienst verwendet, dazu bringen können, auf eine andere Tabelle zu verweisen, können Sie die Spaltengröße in dieser Tabelle erhöhen und den INSTEAD OF INSERT-Trigger verwenden, um das INSERT in die Verkäufertabelle durchzuführen. Eine Variante davon ist, die Tabelle in einer anderen Datenbank zu erstellen und die Standarddatenbank für die Anmeldung des Webdienstes festzulegen.

CREATE TRIGGER [myDB].[mySchema].[TruncDescription] 
ON  [myDB].[mySchema].[myTable] 
INSTEAD OF INSERT
AS 
BEGIN
SET NOCOUNT ON;

INSERT INTO [VendorDB].[VendorSchema].[VendorTable]
SELECT SubType, type, substring(description, 1, 255)
FROM inserted
END

3voto

etoisarobot Punkte 7504

Mit dieser Einstellung funktioniert bei mir alles einwandfrei. Ich will nicht das Offensichtliche behaupten, aber sind Sie sicher, dass im Beschreibungsfeld Daten vorhanden sind, wenn Sie testen? Es ist möglich, dass eines der anderen Felder, die Sie einfügen, ebenfalls geändert wird und vielleicht eines davon den Fehler auslöst.

CREATE TABLE [dbo].[DataPlay](
    [Data] [nvarchar](255) NULL
) ON [PRIMARY]
GO

und einen Auslöser wie diesen

Create TRIGGER updT ON  DataPlay 
Instead of Insert 
AS 
BEGIN
    SET NOCOUNT ON;     
INSERT INTO [tempdb].[dbo].[DataPlay]
           ([Data])
           (Select substring(Data, 1, 255) from inserted)
END
GO

dann einfügen mit

Declare @d as nvarchar(max)
Select @d = REPLICATE('a', 500)
SET ANSI_WARNINGS OFF
INSERT INTO [tempdb].[dbo].[DataPlay]
           ([Data])
     VALUES
           (@d)
GO

1voto

Jim Punkte 1982

Ich bin nicht in der Lage, dieses Problem auf SQL 2008 R2 mit zu reproduzieren:

Declare @table table ( fielda varchar(10) )

Insert  Into @table ( fielda )
Values  ( Substring('12345678901234567890', 1, 10) )

Bitte vergewissern Sie sich, dass Ihr Feld wirklich als varchar(255) definiert ist.

Ich habe auch stark empfehlen wir Ihnen, eine Insert-Anweisung mit einer expliziten Feldliste zu verwenden. Ihre Insert-Anweisung ist zwar syntaktisch korrekt, aber Sie sollten wirklich eine explizite Feldliste verwenden (wie in meinem Beispiel). Das Problem ist, wenn Sie keine Feldliste angeben, sind Sie der Gnade von SQL und der Tabellendefinition bezüglich der Feldreihenfolge ausgeliefert. Wenn Sie tun Wenn Sie eine Feldliste verwenden, können Sie die Reihenfolge der Felder in der Tabelle ändern (oder neue Felder in der Mitte hinzufügen) und sich nicht um Ihre Einfügeanweisungen kümmern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X