用户定义的表类型插入有时会导致转换错误。

17

我有一个名为tvpInsertedColumns的用户定义表类型:

CREATE TYPE [Audit].[tvpInsertedColumns] AS TABLE(
    [ColumnName] [varchar](max) NOT NULL,
    [NewValue] [varchar](max) NULL
)

我正在尝试在存储过程中执行以下操作(@Name和@Phone都是VARCHAR类型)

DECLARE @AuditColumns Audit.tvpInsertedColumns
INSERT INTO @AuditColumns (ColumnName,NewValue)
    SELECT  'Name',@Name UNION ALL
    SELECT  'Phone',@Phone

以下内容出现错误:

将 varchar 值 'Some Name' 转换为数据类型 int 时,转换失败。

但是,在另一个存储过程中我进行了如下操作 (@AddressLine1 和 @AddressLine1 是 VARCHAR 类型):

DECLARE @AuditColumns AS Audit.tvpInsertedColumns
INSERT INTO @AuditColumns (ColumnName,NewValue)
    SELECT  'AddressLine1',@AddressLine1 UNION ALL
    SELECT  'AddressLine2',@AddressLine2

一切都工作得很好。

两个存储过程只是做了一个简单的插入,然后尝试使用该类型和另一个以UDT作为参数的存储过程。

这是我第一次真正接触UDT,所以我希望我只是错过了一些显而易见的东西,但这对我来说毫无意义。如果您需要更多信息,请告诉我。

1个回答

20
DECLARE @AuditColumns Audit.tvpInsertedColumns
INSERT INTO @AuditColumns (ColumnName,NewValue)
SELECT  'Name',@Name UNION ALL
SELECT  'Phone',@Phone

我对UDT不是很了解,但我认为正在发生的事情是:在某个时刻,@name@phone 的值是整数类型。

尝试将@Name和@Phone转换为varchar类型。

INSERT INTO @AuditColumns (ColumnName,NewValue)
SELECT  'Name', cast(@Name as varchar) UNION ALL
SELECT  'Phone', cast(@Phone as varchar)

1
+1,顺便说一句,这不是UDT错误,而是在INSERT之前UNION ALL中的数据类型优先级问题。 - gbn
这不是完全正确的,但它让我找到了解决方案(这就是我想要的)。@Name@Phone 变量从未改变过类型,问题在于在某个时刻(在我的示例截止之后),我还插入了一个整数,假设会自动转换。将所有非 VARCHAR 类型强制转换为 VARCHAR(MAX) 解决了问题。我怀疑 gbn 正确地指出这与 UDT 无关,而是与 UNION 语句中数据类型优先级有关。感谢你们的帮助。 - theChrisKent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接