【发布时间】:2019-03-27 18:33:15
【问题描述】:
我有一个表可以跟踪另一个表的插入、更新和删除。这种模式已经使用了多年,但是当我们添加对 DATE 列的跟踪时突然引入了一个错误。
这不是字符串格式问题。我的输入数据采用 ISO-8601 标准格式。
我已经删除了代码的所有必要部分来演示这个问题。
CREATE TABLE dbo.ChangeTrackingTable
(
oldValue VARCHAR(100) NULL,
newValue VARCHAR(100) NULL
);
GO
CREATE PROCEDURE dbo.usp_TestProcedure
(
@name VARCHAR(100),
@dateOfBirth DATE
)
AS
BEGIN
INSERT INTO dbo.ChangeTrackingTable
(
oldValue,
newValue
)
SELECT
List.oldFieldValue,
List.newFieldValue
FROM
(VALUES
(NULL, @name, IIF(@name IS NOT NULL, 1, 0)),
(NULL, @dateOfBirth, IIF(@dateOfBirth IS NOT NULL, 1, 0))
) AS List (oldFieldValue, newFieldValue, hasChanges)
WHERE
List.hasChanges = 1
END;
GO
VALUES 列表用于动态确定正在触摸哪些列。
当我只使用日期执行存储过程时,一切正常。
DECLARE @date DATE = GETDATE();
EXEC dbo.usp_TestProcedure
@name = NULL,
@dateOfBirth = @date;
/*
oldValue newValue
NULL 2019-03-27
*/
但是,如果我尝试使用为 @name 提供的任何值来执行它,无论是否提供了 @date 的值,我都会收到以下错误。
DECLARE @date DATE = GETDATE();
EXEC dbo.usp_TestProcedure
@name = 'Name',
@dateOfBirth = @date;
--Conversion failed when converting date and/or time from character string.
如果我直接向INSERT 语句提供硬编码值,它就可以正常工作。所以我可以知道它不会在插入时发生在表级别。
如果我向这一行添加显式转换
(NULL, CAST(@dateOfBirth AS VARCHAR(100)), IIF(@dateOfBirth IS NOT NULL, 1, 0))
它也可以。
DATETIMEOFFSET、DATETIME 和 DATETIME2 类型也会出现问题,所以我使用 DATE 不是问题。
我的问题是,当我尝试读取要插入到 VARCHAR 列中的 DATE 值时,为什么会出现 string > datetime 转换错误,但只有在存在另一个时才会出现在 VALUES 列表中List的结果集中的非日期值?
【问题讨论】:
标签: sql-server datetime type-conversion