SQL 通过 dapper 插入的查询以一种方式工作,但不能以另一种方式工作(包括查询)

SQL query to insert via dapper works one way but not the other (queries included)

奇怪的错误来自一个查询而不是另一个,我不确定为什么一个查询有效而另一个无效。

顺便说一下,第二个 Insert 语句处理 FieldA = 单值@var1,FieldB = 值数组和 FieldC = 单值@param3。

还有一点,FieldA + FieldB 是复合唯一约束(但不是外键)

工作版本:

Declare @var1 int 

Insert into table1 (field1, field2) 
values (@param1, @param2); 

select @var1 = SCOPE_IDENTITY()

Insert into table2
    Select FieldA = @var1, FieldB = Id, FieldC = @param3 
    from table3 
    where FieldD = @param4;

Select @var1; 

错误版本(没什么不同,只是 FieldA、B、C 的对齐):

Declare @var1 int 

Insert into table1 (field1, field2) 
values (@param1, @param2); 

select @var1 = SCOPE_IDENTITY()

Insert into table2
    Select FieldA = @var1, FieldC = @param3, FieldB = Id 
    from table3 
    where FieldD = @param4;

Select @var1; 

您似乎(错误地!)假设您在 insert....select 语句的 select 子句中使用的别名决定了值将转到哪些列 - 嗯,那不是它是如何工作的。

就像 insert...values 一样,您应该在 insert 子句中指定列列表(即使它是可选的),就像在 values 子句中一样,顺序select 子句返回的列表示它们将进入的列。

事实上,insert...select 子句中的别名除了有助于提高可读性之外毫无意义——数据库将忽略它们——但如果它们有助于提高可读性,那么保留它们可能不是一个坏选择。

第一个版本只是偶然工作 - 因为 select 子句中列的顺序与 table 本身中列的顺序相匹配 - 或者最糟糕的是,它没有匹配但不匹配的列的数据类型与 select 列表中列的顺序兼容,这意味着您插入了错误的数据而没有得到任何指示。

正确的代码应该是这样的(省略第一个插入语句):

Insert into table2(FieldA, FieldB, FieldC)
Select @var1, Id, @param3 from table3 where FieldD = @param4;

Insert into table2(FieldA, FieldC, FieldB)
Select @var1, @param3, Id from table3 where FieldD = @param4;

这样,您的 insert...select 语句不依赖于 table 本身中列的顺序,并且如果您向 table 添加列也不会中断(除非您添加没有默认值的 non-nullable 列)或者如果您更改 table 中列的顺序(我同意这不太可能,但我已经看到它完成了,比您预期的更频繁)。