Pass datatable as paramater in stored procedure - sql-server

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)

Related

SQL Server Table Valued Parameters

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

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 test data to table-valued parameter within SQL

Is it possible, and if so how, to pass data to a table-valued parameter of a stored function using SQL EXEC?
I know how to pass in data from C#. One of my four stored procs using table-valued parameters is not producing the expected results. I'd like to execute my proc from SQL server management studio for debugging purposes, but I am unable to find the correct syntax for doing so, if such a syntax even exists. I haven't found anything relevant in the docs.
My type table:
CREATE TYPE [MyNameSpace].[MyTypeTable] AS TABLE(
//... all my fields
)
My stored proc:
//... bunch of stuff
ALTER PROCEDURE [MyNameSpace].[MyStoredProc]
#MyTypeTableVar MyTypeTable READONLY
AS
BEGIN
//Do a bunch of stuff
//Want to test the stuff in here
END
I have tried:
IF OBJECT_ID('tempdb.dbo.#MyTempTable') IS NOT NULL DROP TABLE tempdb.dbo.#MyTempTable;
select top 0 *
into #MyTempTable
//existing table with structure that matches the table-valued param
from MyNameSpace.MyTable;
//...Long insert statement assigning test data to #MyTempTable
EXECUTE MyNameSpace.MyStoredProc #MyTypeTableVar = #MyTempTable;
which throws:
Operand type clash: nvarchar is incompatible with MyTypeTable
You can't use a temp table - you have to use a table variable:
declare #t [MyNameSpace].[MyTypeTable]
insert into #t (/*columns*/) values
(/* first row */),
(/* second row */)
EXECUTE MyNameSpace.MyStoredProc #MyTypeTableVar = #t;
(You can populate it with either INSERT ... VALUES as shown above or INSERT ... SELECT if you have an existing table containing the data you care about)
Here's a working example:
-- Declare a table parameter
DECLARE #registryUpdates AS typ_KeyValuePairStringTable;
-- Insert one row
INSERT INTO #registryUpdates
VALUES ('Hello', 'World');
-- Call Stored Procedure
EXEC prc_UpdateRegistry #registryUpdates

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 datatable parameter to stored procedure sql server?

i need to pass data table to the following stored procedure
create procedure insert_data
(#a int ,
#b DataTable)
as
Begin
......
end
i use C#
You will need to do a couple of things to get this going, since you want to pass a table as a parameter you need to create a (1) Table Type and (2) make your store procedure accept a parameter of that type.
Following are the steps required to create a TABLE TYPE .
TABLE TYPE
CREATE TYPE dbo.DataTable AS TABLE
(
-- define table structure here
)
GO
Procedure
Now make you procedure accept a parameter of that table type.
create procedure insert_data
#a int ,
#b dbo.DataTable READONLY --<-- Note this is read only param
as
Begin
......
end
This passed param will be read-only param, so if you need to manipulate the values passed in this param you will need to get these values in a table variable or temp table inside you procedure before you can do any update or insert operations on them.
Consuming C#
You can make use of DataTable class to create a new instance of a that type which matches the you table type in sql server. something like this..
DataTable dt = new DataTable("DataTable");
// Add columns to this object same as the type in sql server
dt.Columns.Add("Column1", typeof(string));
dt.Columns.Add("Column2", typeof(Int32));
//Populate the dt object
dt.Rows.Add("Value1", 1);
dt.Rows.Add("Value2", 2);
dt.Rows.Add("Value2", 3);

Resources