Reputation: 2172
I am getting error:
Invalid object name 'UDTT_SuppliersList'.
Which is User-Defined table type as:
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
I am using it (pass as parameter) with StoredProcedures and it is working fine. But today I tried to pass it as parameter to Table-Valued function. Table is created successfully with no errors. But when I try to call that function it is giving me error as mentioned above.
declare @tbl_UDTT_SuppliersList UDTT_SuppliersList
--declare, and assume populated with data
select* from dbo.GetSupplierInvoicesByDate(@tbl_UDTT_SuppliersList)
Here is the function code:
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
Upvotes: 1
Views: 3596
Reputation: 175736
The problem is with your function:
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
should be:
SELECT
inv.SupplierID as SupplierID
,inv.Amount as InvoiceAmount
FROM dbo.Invoices inv
JOIN @tbl_UDTT_SuppliersList tSupp
ON tSupp.SupplierID = inv.SupplierID;
You may wonder why SQL Server
allows that, answer is simple Deferred Name Resolution
:
When a stored procedure is created, the statements in the procedure are parsed for syntactical accuracy. If a syntactical error is encountered in the procedure definition, an error is returned and the stored procedure is not created. If the statements are syntactically correct, the text of the stored procedure is stored in the sys.sql_modules catalog view.
When a stored procedure is executed for the first time, the query processor reads the text of the stored procedure from the sys.sql_modules catalog view and checks that the names of the objects used by the procedure are present. This process is called deferred name resolution because table objects referenced by the stored procedure need not exist when the stored procedure is created, but only when it is executed.
Consider using inline syntax for better performance:
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);
I suggest also reading about Inline vs Multistatement Table Function
Upvotes: 2