我收到错误:
Invalid object name 'UDTT_SuppliersList'.
用户定义的表类型为:
CREATE TYPE [dbo].[UDTT_SuppliersList] AS TABLE(
[SupplierID] [int] NOT NULL,
[Region_Name] [varchar](255) NULL,
PRIMARY KEY CLUSTERED
(
[SupplierID] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
我正在使用它(传递参数)和StoredProcedures,它工作正常。但是今天我尝试将它作为参数传递给Table-Valued函数。表已成功创建且没有错误。但是,当我尝试调用该函数时,它给出了我上面提到的错误。
declare @tbl_UDTT_SuppliersList UDTT_SuppliersList
--declare, and assume populated with data
select* from dbo.GetSupplierInvoicesByDate(@tbl_UDTT_SuppliersList)
这是功能代码:
ALTER FUNCTION [dbo].[GetSupplierInvoicesByDate]
(
@tbl_UDTT_SuppliersList as dbo.UDTT_SuppliersList READONLY
)
RETURNS
@tableList TABLE(
SupplierID int,
InvoiceAmount decimal(19, 3)
)
AS
BEGIN
INSERT INTO @tableList (
SupplierID,
InvoiceAmount
)
SELECT
inv.SupplierID as SupplierID
,inv.Amount as InvoiceAmount
FROM dbo.Invoices inv
inner join UDTT_SuppliersList tSupp on tSupp.SupplierID = inv.SupplierID
WHERE inv.IsPaidFully = 0
RETURN
END
答案 0 :(得分:1)
问题在于你的功能:
SELECT
inv.SupplierID as SupplierID
,inv.Amount as InvoiceAmount
FROM dbo.Invoices inv
inner join UDTT_SuppliersList tSupp -- use use type, not table variable
on tSupp.SupplierID = inv.SupplierID
应该是:
SELECT
inv.SupplierID as SupplierID
,inv.Amount as InvoiceAmount
FROM dbo.Invoices inv
JOIN @tbl_UDTT_SuppliersList tSupp
ON tSupp.SupplierID = inv.SupplierID;
您可能想知道为什么SQL Server
允许这样做,答案很简单 Deferred Name Resolution
:
创建存储过程时,过程中的语句 被解析为语法准确性。如果出现语法错误 在过程定义中遇到,返回错误并且 未创建存储过程。如果语句是语法上的 更正,存储过程的文本存储在 sys.sql_modules目录视图。
第一次执行存储过程时,查询 处理器从中读取存储过程的文本 sys.sql_modules目录视图并检查对象的名称 程序使用的程序存在。 此过程称为延迟 名称解析,因为存储的引用的表对象 创建存储过程时,不需要存在过程,但是 只有在执行时才会执行。
考虑使用内联语法以获得更好的性能:
ALTER FUNCTION [dbo].[GetSupplierInvoicesByDate](
@tbl_UDTT_SuppliersList as dbo.UDTT_SuppliersList READONLY)
RETURNS TABLE
AS
RETURN (SELECT
inv.SupplierID AS SupplierID
,inv.Amount AS InvoiceAmount
FROM dbo.Invoices inv
JOIN @tbl_UDTT_SuppliersList tSupp
ON tSupp.SupplierID = inv.SupplierID
WHERE inv.IsPaidFully = 0);