SQL Server Table Valued Parameters - sql-server

I am attempting to create a table valued parameter for input into an MS SQL Server stored proc. My create statement:
CREATE TYPE dbo.tvt_AbusedBy AS TABLE
( Assessment_Behavorial_AbusedID int, Assessment_BehavorialID int,
Ref_Abuse_TypeID int, Abuser_Name varchar(50), GenderID int,
Relationship_TypeID int, Age int)
When attempting to add as a parameter into the proc:
CREATE PROCEDURE [dbo].[qryAddUpdateMultipletblAssessment_Behavorial_Abused]
#prm_Assessment_Abused AS dbo.tvt_AbusedBy READONLY,
I get an error reading "The parameter #prm_Assessment_Abused cannot be declared READONLY since it is not a table valued parameter".
It does not seem to recognize it as a table valued parameter.
If I remote the READONLY stipulation, it gives me an error "Parameter or variable #prm_Assessment_Abused has an invalid type.
Must be an issue with how I am attempting to create the table valued parameter type.
Any ideas?

Don't use AS when adding parameters in a stored procedure declaration:
CREATE PROCEDURE [dbo].[qryAddUpdateMultipletblAssessment_Behavorial_Abused]
#prm_Assessment_Abused dbo.tvt_AbusedBy READONLY

From MS documentation - https://learn.microsoft.com/en-us/sql/t-sql/statements/create-procedure-transact-sql?view=sql-server-2017
You don't need AS before parameters, use it afters parameters declaration.
Example from link (a little edited):
CREATE PROCEDURE dbo.usp_add_kitchen
#dept_id int, #kitchen_count int NOT NULL
AS
BEGIN
UPDATE dbo.Departments
SET kitchen_count = ISNULL(kitchen_count, 0) + #kitchen_count
WHERE id = #dept_id
END;
GO

Related

Getting Error Msg: Must declare the scalar variable

I used this code in SQL Server:
CREATE TYPE ExampleType AS TABLE (Number INT)
GO
CREATE FUNCTION GetExampleTableType(#InputNumber INT)
RETURNS ExampleType
AS
BEGIN
DECLARE #OutputTable ExampleType;
INSERT INTO OutputTable
VALUES (#InputNumber);
RETURN(#OutputTable);
END;
GO
But I got an error:
Must declare the scalar variable "#OutputTable"
I have declared #OutputTable but it cannot be a scalar value, it must be a table.
What is wrong?
You are trying to return table variable from scalar valued User defined function. You need to convert the function as given below to store the values into the table valued parameter.
Also, read this StackOverFlow Post, where you cannot return UDT from table valued function.
CREATE TYPE ExampleType AS TABLE (Number int)
GO
CREATE Function GetExampleTableType(#InputNumber int)
RETURNS Table
AS
RETURN
(SELECT #InputNumber AS int);
DECLARE #OutputTable ExampleType
INSERT INTO #OutputTable
SELECT * FROM dbo.GetExampleTableType (1);
Actually you don't need to create a user-defined table type. You can directly give table instead of that.
Query
CREATE Function GetExampleTableType(#InputNumber int)
RETURNS #OutputTable TABLE
(
Number int
)
AS
BEGIN
INSERT INTO #OutputTable VALUES (#InputNumber);
RETURN;
END;
As per my understanding we can use tabletype variables to pass as arguments to functions and stored procedures but not used in multistatemnet table valued functions like you mentioned in the question. But in your example you try to access tabletype variable in returns clause which is syntactically incorrect.
This is what i have as sample code here to use tabletype variables in functions context.. please let me know if any thing i missed to understand your question...
CREATE TYPE TableType
AS TABLE (LocationName VARCHAR(50))
GO
CREATE FUNCTION Example( #TableName TableType READONLY)
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE #name VARCHAR(50)
SELECT #name = LocationName FROM #TableName
RETURN #name
END
DECLARE #myTable TableType
INSERT INTO #myTable(LocationName) VALUES('aaa')
SELECT dbo.Example(#myTable)
Table-valued parameters have the following restrictions:
SQL Server does not maintain statistics on columns of table-valued parameters.
Table-valued parameters must be passed as input READONLY parameters to Transact-SQL routines. You cannot perform DML operations such as UPDATE, DELETE, or INSERT on a table-valued parameter in the body of a routine.
You cannot use a table-valued parameter as target of a SELECT INTO or INSERT EXEC statement. A table-valued parameter can be in the FROM clause of SELECT INTO or in the INSERT EXEC string or stored procedure.
Reference: https://learn.microsoft.com/en-us/sql/relational-databases/tables/use-table-valued-parameters-database-engine?view=sql-server-2017

calling a synonym of a procedure where input parameter is user-defined table type

On DatabaseA I have User-Defined Data Type which is used as input parameter in a stored procedure. On another database (DatabaseB) I am creating synonym to this procedure and I am creating same data type there.
When I call the sysnonym I am reciving an error "Operand type clash: Ids is incompatible with Ids"
Any suggestion how to resolve this problem?
use DatabaseA
go
CREATE TYPE [dbo].[Ids] AS TABLE(
[Id] [sql_variant] NULL
)
GO
create procedure dbo.proc1 #Ids [Ids] readonly
as
begin
select *
from #Ids;
end
declare #Ids dbo.Ids;
insert into #Ids values (1),(2)
exec dbo.proc1
#Ids = #Ids
use DatabaseB
CREATE TYPE [dbo].[Ids] AS TABLE(
[Id] [sql_variant] NULL
)
go
CREATE SYNONYM [Admiral_CentralSystem01].[dbo_proc1] FOR [Admiral_CentralSystem01].[dbo].[proc1]
GO
declare #Ids dbo.Ids;
insert into #Ids values (1),(2)
exec [Admiral_CentralSystem01].[dbo_proc1]
#Ids = #Ids
You cannot pass Table variables as parameter in another db.
XML variable with XPath can solve your problem
Basically tables variant are database scoped
In order to use a user-defined type (UDT) in Microsoft SQL Server, you
must register it. Registering a UDT involves registering the assembly
and creating the type in the database in which you wish to use it.
UDTs are scoped to a single database, and cannot be used in multiple
databases unless the identical assembly and UDT are registered with
each database. Once the UDT assembly is registered and the type
created, you can use the UDT in Transact-SQL and in client code. For
more information, see CLR User-Defined Types.
https://learn.microsoft.com/en-us/sql/relational-databases/clr-integration-database-objects-user-defined-types/registering-user-defined-types-in-sql-server

Pass TABLE as parameter without creating TYPE

I know it is possible to create a stored procedure and pass a TABLE as parameter by doing the following:
CREATE TYPE MyTableType AS TABLE (Id UNIQUEIDENTIFIER)
CREATE PROCEDURE MyProcedure
#ids MyTableType READONLY
AS
...
I don't want to create a TYPE as above, because I was told to not create type dependencies in the database. So I want to do the following:
CREATE PROCEDURE MyProcedure
#ids TABLE (Id UNIQUEIDENTIFIER)
AS
But for some reason I get error highlights. Am I doing something wrong in the syntax? Or is this not possible to do?
I don't think it's possible to declare a table type inline like you're trying to do. The first line in this article on table-valued parameters says:
Table-valued parameters are declared by using user-defined table types.

How to pass string array in 'In' clause in sql stored procedure

I have user table in database storing user information. I want to create stored procedure in which I will pass UserIDs as a list. I want to use this list to fetch data from user table.
I am creating type as a table using following query:
CREATE TYPE dbo.MyUserIDs AS TABLE (UserID int)
Now I am using this type in stored procedure:
ALTER PROCEDURE [dbo].[Test_in_Query]
#MyUserids MyUserIDs READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT * From Tbl_UserMast where UserID in (select UserID from #MyUserids)
END
When I execute this code I am getting following error:
Operand type clash: int is incompatible with MyUserIDs
I am following this link as a reference:
Reference link
I am directly executing stored procedure in sql server
I don't think you can pass a TVP-value using the SSMS gui (or at least I'm not aware of how to do it), but you have to do it in t-sql code, like so:
-- declare a variable using the user-defined type
DECLARE #MyUsers MyUserIDs
-- insert some data into it
INSERT INTO #MyUsers(UserID) VALUES (1),(2),(4)
-- and pass it into the proc
EXEC Test_in_Query #MyUserids = #MyUsers

Pass datatable as paramater in stored procedure

Is it possible to pass datatable as parameter into stored procedure ?
So, something like
exec MyStoredProcedure #MyDataTable
I am using SQL SERVER 2008.
You need to create User-defined Table Type first.
-- Create the data type
CREATE TYPE udtt_Table AS TABLE
(
Column1 int,
Column2 varchar(10),
Column3 datetime
)
GO
You can use user-defined table type in your stored procedure like the following,
CREATE PROCEDURE usp_User
(
#UserTable udtt_Table READONLY
)
...
....
You could create your own type: https://msdn.microsoft.com/en-us/library/ms175007.aspx
But it's quite a work... What exactly do you want to reach?
EDIT: Another suggestion
Use an XML-Parameter (see comments below)

Resources