Nested Create Type in Stored Procedure Declaration T-SQL - sql

I am writing a SQL Stored Proc which takes in a single table valued parameter. Is it possible for me to create the table type in the parameter definition, for example:
CREATE PROCEDURE example (
#param (CREATE TYPE tableparameter ( column1 int, colunn2 varchar.... )) READONLY
)

No.
Databases will want the type to already exist before it can be specified as a parameter type, otherwise the database has no way to know if the data it is receiving is valid or not.

Related

sp_executesql with user defined table type not working with two databases [duplicate]

I'm using SQL Server 2008.
How can I pass Table Valued parameter to a Stored procedure across different Databases, but same server?
Should I create the same table type in both databases?
Please, give an example or a link according to the problem.
Thanks for any kind of help.
In response to this comment (if I'm correct and that using TVPs between databases isn't possible):
What choice do I have in this situation? Using XML type?
The purist approach would be to say that if both databases are working with the same data, they ought to be merged into a single database. The pragmatist realizes that this isn't always possible - but since you can obviously change both the caller and callee, maybe just use a temp table that both stored procs know about.
I don't believe it's possible - you can't reference a table type from another database, and even with identical type definitions in both DBs, a value of one type isn't assignable to the other.
You don't pass the temp table between databases. A temp table is always stored in tempdb, and is accessible to your connection, so long as the connection is open and the temp table isn't dropped.
So, you create the temp table in the caller:
CREATE TABLE #Values (ID int not null,ColA varchar(10) not null)
INSERT INTO #Values (ID,ColA)
/* Whatever you do to populate the table */
EXEC OtherDB..OtherProc
And then in the callee:
CREATE PROCEDURE OtherProc
/* No parameter passed */
AS
SELECT * from #Values
Table UDTs are only valid for stored procs within the same database.
So yes you would have to create the type on each server and reference it in the stored procs - e.g. just run the first part of this example in both DBs http://msdn.microsoft.com/en-us/library/bb510489.aspx.
If you don't need the efficency you can always use other methods - i.e. pass an xml document parameter or have the s.p. expect a temp table with the input data.
Edit: added example
create database Test1
create database Test2
go
use Test1
create type PersonalMessage as TABLE
(Message varchar(50))
go
create proc InsertPersonalMessage #Message PersonalMessage READONLY AS
select * from #Message
go
use Test2
create type PersonalMessage as TABLE
(Message varchar(50))
go
create proc InsertPersonalMessage #Message PersonalMessage READONLY AS
select * from #Message
go
use Test1
declare #mymsg PersonalMessage
insert #mymsg select 'oh noes'
exec InsertPersonalMessage #mymsg
go
use Test2
declare #mymsg2 PersonalMessage
insert #mymsg2 select 'oh noes'
exec InsertPersonalMessage #mymsg2
Disadvantage is that there are two copies of the data.
But you would be able to run the batch against each database simultaneously.
Whether this is any better than using a table table is really down to what processing/data sizes you have - btw to use a temp table from an s.p. you just access it from the s.p. code (and it fails if it doesn't exist).
Another way to solve this (though not necessarily the correct way) is to only utilize the UDT as a part of a dynamic SQL call.
USE [db1]
CREATE PROCEDURE [dbo].[sp_Db2Data_Sync]
AS
BEGIN
/*
*
* Presumably, you have some other logic here that requires this sproc to live in db1.
* Maybe it's how you get your identifier?
*
*/
DECLARE #SQL VARCHAR(MAX) = '
USE [db2]
DECLARE #db2tvp tableType
INSERT INTO #db2tvp
SELECT dataColumn1
FROM db2.dbo.tblData td
WHERE td.Id = ' + CAST(#YourIdentifierHere AS VARCHAR) '
EXEC db2.dbo.sp_BulkData_Sync #db2tvp
'
EXEC(#SQL)
END
It's definitely not a purist approach, and it doesn't work for every use case, but it is technically an option.

Creating a table type param in SQL Server Stored Procedure

Is it possible to declare/create the table type param(TVP) in Stored Procedure itself instead of creating the table value type separately in the schema and then using it in Stored procedure. i.e.,
create procedure proc1(
#table1 table(id int) readonly
)
as
begin
select top 1 * from sysobjects
end
From MSDN:
Table-valued parameters are based on strongly-typed table structures
that are defined by using Transact-SQL CREATE TYPE statements. You
have to create a table type and define the structure in SQL Server
before you can use table-valued parameters in your client
applications.
So it is clearly said that you can't declare TVP in stored procedure like you want - only by creating as user-defined type.

SELECT Query selecting values based on a value in another table

I have 2 tables
Account(AccountId, Encoding)
DeviceAccountMap(AccountId, DeviceId)
Now I need to fetch the devices from the DeviceAccountMap. I pass a list of AccountId to a stored procedure and while fetching the DeviceId from the DeviceAccountMap table I need to compare the Encoding value for each account with a particular value.
Which is the easy way to do this? I am totally lost.
The select clause in the stored procedure will look something like this:
DECLARE #Accounts [usp].[Array]
and [usp].[Array] is defined as below
CREATE TYPE [usp].[Array] AS TABLE
(
Value VARCHAR(36) NULL
)
SELECT
DeviceId,
AccountEncoding = A.Encoding
FROM
usp.DeviceControllerAccountMap DCAM
INNER JOIN
usp.Account A ON (DCAM.AccountId = A.AccountId)
WHERE
DCAM.AccountId IN (SELECT Value From #AccountIds)
AND DCAM.IsShared = 1
AND AccountEncoding LIKE A.Encoding + '.%'
In other words I need to fetch the encoding value for each account and use that in this where clause.
So you can look up information on Table-Valued Parameters (TVPs) in T-SQL.
Here is an article by Erland Sommarskog.
You can refer to this StackOverflow answer to see an example of C# code calling a stored procedure that uses a TVP. I believe TVPs require SQL Server 2008 or higher.
TVPs, as far as I understand, provide a way to make your own data type in sql server that gets treated as if it was a table. You're doing this when you declare your Array type and then when you use the #AccountIds in your stored procedure's select statement.
CREATE TYPE [usp].[Array] AS TABLE -- maybe choose a more descriptive name than 'Array'
(
Value VARCHAR(36) NULL -- choose a more descriptive name than 'Value'
)
CREATE PROCEDURE [usp].[your_procedure_name]
#AccountIds [usp].[Array] READONLY -- use TVP as a parameter
AS
SELECT …
It is not clear form your question details whether you also mean to have a parameter in the stored procedure for the Encoding. It seems like you're looking for accounts whose Encodings start with a period '.'.
So first, create your type, like you're doing.
Then create your stored procedure.
Then test your stored procedure, something like this:
DECLARE #mylist Array -- make TVP sample data
INSERT #mylist(Value) VALUES(1),(11),(27),(123) -- insert some values
exec your_procedure_name #mylist -- run stored procedure
The following line is completely unnecessary. The JOIN to Account does this filter for you.
DCAM.AccountId IN (SELECT Value From #AccountIds)
Or am I missing something?

cant set OUTPUT to return a table from another stored procedure

I am trying to create a stored procedure which returns a temp table to another stored procedure. However, I cannot seem to be able to set a table as an output variable. For instance:
#t table(ID int) output
as a parameters does not work. However the following does not complain:
#t int output
Is there a way to get one stored procedure to obtain a table generated by another stored proceedure? Thanks ahead of time!
The answer is No.
You could pass the name of the created table from one Stored Procedure to another and then in the second SP you can use the name to query thru the table.
Yes, you can achieve this by using a User Defined Table Type. All you need to do is
Create a User defined Table Type.
Create your first Stored Procedure to Accept a Table Type variable.
In your second procedure declare a Table Type variable, populate it with the data you want and call the first procedure by passing in the Table Type variable.
Here is a sample code.
1) Create the User Defined Table Type. Under the Programmability -- > Types -- > User Defined Table Types -- > Right click to create your table type
CREATE TYPE [schemaname].[Ttype] AS TABLE
(
EmployeeID int,
EmployeeName varchar(100),
)
GO
The above type is just an example, put in the columns that you require in it. Here Ttype is the Name of the TableType (you can name it as per your convenience)
2) Create your first stored procedure that will accept the Table type as variable so that you can use it.
CREATE PROCEDURE [schemaname].[StoredProcName]
#TableType Ttype READONLY
AS
BEGIN
-- Just an example on how to use the TableType.
INSERT INTO TableName(EmployeeId,EmployeeName)
SELECT EmployeeID,EmployeeName FROM #TableType
END
GO
The above Stored Procedure accepts a Table Type variable. The Ttype indicates that the #Tabletype variable is user defined table type. The READONLY indicates that no DML operations can be performed on the Table type parameter.
3) Now, create your second procedure that will pass the Table Type parameter to the above procedure created.
CREATE PROCEDURE [schemaname].[StoredProc2Name]
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Table as Ttype
INSERT INTO #Table(EmployeeID,EmployeeName)
SELECT EmployeeID,EmployeeName FROM schemaname.Employees
EXEC [schemaname].[StoredProcName] #Table
END
GO
In the above SP, you declare a variable named #Table which is of the Table Type (Ttype). Now you populate it with the data you need and then call the first procedure by passing in the #Table variable.

SQL - Need to run stored proc with ~100 different params, what's the best way to do this?

Assuming I have a table with one field called ID that stores 100 different integer values. I can select all of these rows simply by doing select id from example_table
I then have a stored procedure that I need to execute for each of these id's (as the sole parameter) and then select specific columns from (the stored procedure returns more data then I need). Besides executing the stored procedure 100 separate times into a temporary table and then selecting data from this table - how else could I do this?
You can pass table parameter to the procedure.
Check http://www.techrepublic.com/blog/datacenter/passing-table-valued-parameters-in-sql-server-2008/168
Update
CREATE TYPE LIST_OF_ID TABLE (ID INT);
go
CREATE PROCEDURE PROC1(#ids LIST_OF_ID READONLY)
....