我已经找到了所有我能找到的方法,但找不到初始化DataTable以匹配数据库中声明的UDT表的技术。我可以手动浏览和添加列,但我不想在这两个地方重复结构。对于普通表,一种选择是简单地发出"select*where…",但不返回结果。但是,对于UDT表,可以这样做吗?
这是背景问题。
此数据库有一个存储过程,它接受表值参数,该参数是在同一数据库中声明的指示UDT表的实例。大多数UD字段都可以为null,并且加载TVP的逻辑非常复杂。我希望做的是初始化DT,然后根据需要插入行,并在执行过程中设置所需的列/字段值,直到我准备好将结果提交给SS进行最终处理。
我当然可以在代码中添加十几个或更多的字段,但细节仍在变化中(可能会持续一段时间),这也是我不想在代码中加载所有列的原因之一。
那么,有一个合理的解决方案吗,还是我找错了树?我已经花了更多的时间来寻找我期望存在的解决方案,而不是写100遍列加载代码,但现在我只想知道这是否可能。
好吧,我和一个比我更懂SQL的朋友讨论过(不需要太多),他建议使用以下SQL查询:
"声明@TVP为MyUDTTable;从@TVP中选择*"
这似乎正是我想要的,所以如果其他可怜的树液将来想要类似的东西,我会在这里更新。也许其他人可能会提供不同或更好的答案。
下面是我如何做到这一点的一个例子。这种输入/输出风格是我和一位同事共同打造的,可以快速有效地使用他身边的实体框架,并让我可以选择使用所有sql玩具。如果这与您的使用相同,您可能也会喜欢我在这里使用的OUTPUT。它将新创建的id直接吐回调用proc的任何方法,允许程序直接进行下一个活动,而无需纠缠我的数据库来获取数字。
我的Udt
CREATE TYPE [dbo].[udtOrderLineBatch] AS TABLE
(
[BrandId] [bigint] NULL,
[ProductClassId] [bigint] NULL,
[ProductStatus] [bigint] NULL,
[Quantity] [bigint] NULL
)
并且将其作为输入的过程
create procedure [ops].[uspBackOrderlineMultipleCreate]
@parmBackOrderId int
,@UserGuid uniqueidentifier
null
,@parmOrderLineBatch as udtOrderLineBatch readonly
as
begin
insert ops.OrderLine
(
BrandId
,ProductClassId
,ProductStatusId
,BackOrderId
,OrderId
,DeliveryId
,CreatedDate
,CreatedBy)
output cast(inserted.OrderLineId as bigint) OrderLineId
select line.BrandId
,line.ProductClassId
,line.ProductStatus
,@parmBackOrderId
,null
,null
,getdate()
,@UserGuid
from @parmOrderLineBatch line
join NumberSequence seq on line.Quantity >= seq.Number
end