我有一个SQL存储过程,它接受默认值为NULL 的DateTime参数
@pmNext_Check_Date DATETIME=NULL
我想在 3 种情况下使用此参数:
- 如果为 NULL,则不更新任何记录
- 如果它有一个日期值,则更新我在 WHERE 子句中指定的所有记录
- 问题一!将查询中的所有日期字段设置为 WHERE 子句中记录的 NULL。
这是 SP 中导致我出现问题的代码块(UPDATE 语句的其余部分是在 SP 中的其他地方构建的,工作正常):
IF @pmNext_Check_Date IS NOT NULL
IF @pmNext_Check_Date ='' --This is the bit that is causing me a problem. I just need to check for a empty date
SET @sql = @sql + ' Next_Check_Date = NULL '
ELSE
SET @sql = @sql + ' Next_Check_Date = @pmNext_Check_Date '
SET @sql = @sql + ' WHERE ID IN (1, 2)'
例如,如果我有以下 2 行:
ID 下一个检查日期
12-12-12
2 空
在场景 1 中,我不会将参数传入,因为该过程将使用默认值,并且不会更新任何日期。
在场景 2 中,我传入一个日期值并使用日期值更新两行
在方案 3 中,我想将行上的日期值更新为 null。方案 1 和方案 3 之间的区别在于,在方案 3 中,用户将选择将日期值设置为 null。
因此,我想将一个空白日期传递到存储过程中。我正在从 C# 执行此操作,并希望执行以下操作:
SqlParameter param = new SqlParameter("@pmNext_Check_Date", "");
此操作失败,因为 SP 需要日期时间。
所以我希望能够传入一个空白日期,以及如何在SP中检查这一点。下面的当前检查不起作用:
IF @pmNext_Check_Date =''
提前谢谢。希望这一切都有意义。我正在使用 C#4.0 和 SQL 2008
没有"空白日期"这样的东西。您可以使用众所周知的哨兵值(例如,01 Jan表示某个任意的古代年份),但null
更可取。请注意,要通过参数传递显式null
,您需要:
SqlParameter param = new SqlParameter("@pmNext_Check_Date", DBNull.Value);
如果这没有足够的粒度,请考虑添加一个单独的布尔 ( bit
) 参数(或类似参数)来阐明您希望 sproc 执行的操作。或者:有多个过程来做这些不同的事情。
的一个有用的哨兵值是 1753 年 1 月 1 日(SQL Server 的最小datetime
值) - 可以在 TSQL 中生成,而无需将字符串解析为 cast(-53690 as datetime)
。
不能将空字符串作为日期时间传递。 因此,您有几个选择。 您可以添加其他参数来指示是否应进行更新。 我建议将其作为代码可读性和可维护性的最佳选择。 另一种选择是将参数作为字符串传入并解析它。 这样您就可以使用空字符串概念。
SQL 服务器字符串到日期的转换
抱歉,没有办法准确地按照您的要求进行操作。DATETIME
值要么是NULL
日期,要么是有效日期,没有像字符串那样的"空"。
另一种解决方法是传递一个令牌值(否则不是有效日期)来表示所谓的空字符串,例如,我看到的一个常用的字符串是 1900-01-01
.然后,可以在存储过程中区分NULL
和"空"。
但我根本不建议这样做。我同意其他建议:添加另一个参数并在存储过程中以更有意义的方式执行逻辑。
没记错的话,具有允许 NULLS 的 DATETIME 数据类型的列将默认为值 1900-01-01 而不是 BLANK 值。
例如:对于某些列,可能允许使用 NULLS,这些列可能会在以后根据某种业务逻辑接收值。我已经看到人们将这些开放式列保留为 varchar 以启用某种类型的自定义条目或空字符串,这是 datetime 不允许的。
如果你问我,我会尽量不要弄乱基列的数据类型,让它保留为 DATETIME。出于数据检索和报告的目的,我们可能会尝试以下方法,这可能不是最佳方法。但它有效。
BEGIN
DECLARE @VarcharDateTable TABLE
([EndDate_Varchar] varchar(27))
BEGIN
INSERT INTO @VarcharDateTable([EndDate_Varchar])
SELECT
CONVERT(varchar(27), [EndDate_Datetime], 121)
FROM [dbo].[MainTable]
END
BEGIN
SELECT CASE WHEN [EndDate_Varchar] LIKE '1900-01-01%'
THEN 'Data unavailable'--or whatever you want
ELSE [EndDate_Varchar]
END AS [EndDate_Varchar] FROM @VarcharDateTable
END
END