我们使用一个决定从255改变字段最大长度的Web服务。我们的末端有一个旧的供应商表,仍然限制在255.我们希望暂时使用触发器来解决这个问题,直到我们可以在下一次迭代中实现更加商业友好的解决方案。
以下是我的开始:
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
但是,当我尝试在myTable
上插入时,我收到错误:
字符串或二进制数据 截断。声明一直如此 终止。
我尝试使用SET ANSI_WARNINGS OFF
进行试验,这样可以使查询正常工作,但之后只是没有在说明列中插入任何数据。
有没有办法使用触发器来截断太长的数据,还是有其他替代方法我可以使用,直到可以设计出更有说服力的解决方案?我们在表修改方面相当有限(即我们不能),因为它是供应商表,我们不控制我们正在使用的Web服务,所以我们也不能要求他们修复它。任何帮助将不胜感激。
答案 0 :(得分:2)
通过此设置,一切正常。 不要说明显而易见但是你确定在测试时说明字段中有数据吗?他们有可能更改你插入的其他字段之一,也许其中一个是抛出错误?
CREATE TABLE [dbo].[DataPlay](
[Data] [nvarchar](255) NULL
) ON [PRIMARY]
GO
和像这样的触发器
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
然后插入
Declare @d as nvarchar(max)
Select @d = REPLICATE('a', 500)
SET ANSI_WARNINGS OFF
INSERT INTO [tempdb].[dbo].[DataPlay]
([Data])
VALUES
(@d)
GO
答案 1 :(得分:2)
无法避免错误,因为填充插入的表时会发生错误。
从文档中: http://msdn.microsoft.com/en-us/library/ms191300.aspx
“inserted和deleted表的格式与定义INSTEAD OF触发器的表的格式相同。inserted和deleted表中的每一列都直接映射到基表中的一列。”< / p>
我能想到的唯一真正“聪明”的想法是利用模式和登录使用的默认模式。如果您可以获取Web服务用于引用另一个表的登录名,则可以增加该表上的列大小,并使用INSTEAD OF INSERT触发器对供应商表执行INSERT。其中一个变体是在不同的数据库中创建表,并为Web服务登录设置默认数据库。
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
答案 2 :(得分:1)
我无法使用以下方法在SQL 2008 R2上重现此问题:
Declare @table table ( fielda varchar(10) )
Insert Into @table ( fielda )
Values ( Substring('12345678901234567890', 1, 10) )
请确保您的字段确实定义为varchar(255)。
我还强烈建议您使用带有显式字段列表的Insert语句。虽然您的Insert在语法上是正确的,但您确实应该使用显式字段列表(就像在我的示例中一样)。问题是当您没有指定字段列表时,您将受SQL的限制和字段顺序的表定义。当您执行使用字段列表时,您可以更改表中字段的顺序(或在中间添加新字段),而不关心插入语句。