无法通过 UDT 插入到具有默认值的不可为空的列中

本文关键字:默认值 UDT 插入 | 更新日期: 2023-09-27 18:36:07

抱歉,我不知道如何以简单明了的方式正确描述我的问题。我粘贴了我的代码的简化版本,希望它能很好地解释。

我有一个表,其中有一个默认值为不可空的列:

CREATE TABLE [dbo].[DemoTable] (
...
[DemoColumn] [varchar](200) NOT NULL DEFAULT('None')
...
)

并且有一个过程通过 UDT UDT_Demo更新 DemoTable

CREATE PROCEDURE pr_Update_DemoTable
    @demoUDT UDT_Demo READONLY
AS
BEGIN
    MERGE DemoTable
    USING @demoUDT
    ON ...
    WHEN MATCHED
    THEN UPDATE
    SET ...
        DemoTable.DemoColumn = @demoUDT.DemoColumn,
        ...
    WHEN NOT MATCHED BY TARGET
    THEN INSERT
    (... DemoColumn ... ) VALUES (... @demoUDT.DemoColumn ...)
END 

UDT_Demo定义为:

CREATE TYPE UDT_Demo AS TABLE
(
...
[DemoColumn] [varchar](200) NULL
...
)

以下是我在 C# 代码中调用 proc pr_Update_DemoTable的方式:

DataTable udt_Demo = new DataTable();
...
udt_Demo.Columns.Add("DemoColumn");
...
udt_Demo.Rows.Add(new object[] { ... demoColumnValue ... }); // demoColumnValue is null in this case
SqlCommand command = new SqlCommand("pr_Update_DemoTable");
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("demoUDT", udt_Demo);
... // some addtional logic to prepare for the execution
command.ExecuteNonQuery();

此代码将给出异常"无法将 NULL 插入 DemoTable.DemoColumn,因为 DemoColumn 不可为空"

======

=我尝试过的其他方法======

方法1:

如果我将UDT_Demo定义修改为

CREATE TYPE UDT_Demo AS TABLE
(
...
[DemoColumn] [varchar](200) NOT NULL DEFAULT('None')
...
)

异常消息将变为"无法将 NULL 插入 UDT_Demo.演示列,因为演示列不可为空"

方法2:

如果我没有在 C# 代码中指定 DemoColumn 值,则会出现异常"插入的值数与表中的列数不匹配"

方法3:

这目前有效,但并不理想。我不想对默认值进行硬编码。

DataTable udt_Demo = new DataTable();
...
udt_Demo.Columns.Add("UDTColumn");
...
udt_Demo.Rows.Add(new object[] { ... demoColumnValue ?? "None" ... });
... // the rest of the code is the same

无法通过 UDT 插入到具有默认值的不可为空的列中

如果您希望SQL使用默认值,则不应在insert语句中声明该列。

CREATE TABLE [dbo].[testDefault](
[col1] [int] NULL,
[col2] [varchar](50) NULL,
[col3] [nchar](10) NOT NULL
) ON [PRIMARY]
ALTER TABLE [dbo].[testDefault] ADD  CONSTRAINT [DF_testDefault_col3]  DEFAULT ('test') FOR [col3]

插入数据

INSERT INTO testDefault
(col1, col2)
VALUES(1, 'TEST') -- not declaring col3

从表中选择

SELECT * FROM testDefault

会给你结果

col1    col2        col3
1       TEST        test      

您可以通过使用以下DemoColumn设置值来更新pr_Update_DemoTable过程

IFNULL(@demoUDT.DemoColumn, 'None')