Select Stored Procedure Outputs On-the-Fly (SQL Server) - sql

I am trying to pass an output parameter from a stored procedure into another stored procedure. The parent needs to pass a parameter into the child.
Can I return the output on-the-fly in a select statement like this?
If not, what is a good way to approach this problem?
Stored Procedure (Child)
#uid int,
#result nvarchar(max) output
as
begin select #result = stuff((
select
'cid' = cid
from db
for xml path('')
),
1,
1,
'<'
)
return
end
Stored Procedure (Parent)
select
'id' = uid,
'result' = (exec db.dbo.table uid, #result output)
from table
Here I am trying to pass in a uid from the parents select statement, and pass it into another stored procedure, and return the result in a select.

This might be what you're after, however, the fact that you have a EXEC statement in your SELECT make me think otherwise.
CREATE PROC Child #uid int, #result nvarchar(MAX) OUTPUT AS
SELECT #result = STUFF((SELECT cid AS cid
FROM db
--Should there be a WHERE here?
FOR XML PATH(N'')),1,1,N'<');
GO
CREATE PROC Parent #uid int AS
DECLARE #result nvarchar(MAX);
EXEC Child #uid, #result OUTPUT;
SELECT #uid UID, #result AS Result;
GO
That is more of a literal copy of what you have in your question though. It might be that this is more what you're after with an inline-table function:
CREATE FUNCTION Child (#uid int)
RETURNS TABLE
AS RETURN
SELECT STUFF((SELECT cid AS cid
FROM db
--Should there be a WHERE here?
FOR XML PATH(N'')),1,1,N'<') AS cid;
GO
CREATE PROC Parent #uid int AS
SELECT #uid UID,
C.cid
FROM [Table]
CROSS APPLY dbo.Child(#uid) C
GO
Like I said in the comments, it seems we're missing a WHERE or something here.

Related

T-SQL Execute from a stored procedure

I am trying to build an SQL inside a stored procedure and execute it using
EXEC sp_executesql
Now I defined a local table and tried to pass it in need to pass it in
CREATE TYPE mytabletypeAS TABLE (
StartDate DATETIME,
EndDate DATETIME,
Amount MONEY,
AccountId INT
);
The following happens in my stored procedure, what I am trying to do is to return the output produced by EXEC sp_executesql:
CREATE PROCEDURE attributevalues.sp_EvalClearingNetSpend
AS
BEGIN
DECLARE #OutPutTable AS mytabletype;
DECLARE #Sql AS NVARCHAR(MAX);
SET #Sql = 'INSERT INTO #OutPutTable SELECT StartDate,EndDate,Amount, AccountId FROM table1';
EXEC sp_executesql #Sql, N'#OutPutTable mytabletype OUTPUT', #OutPutTable OUTPUT;
SELECT * FROM #OutPutTable
END
The above is saying I cannot pass in OUTPUT with #OutPutTable
Help!!!
all i need to know is, is there a way I can get the values from a statement executed via EXEC and return it from my SP
Yes. But you can't do it with a table variable. You can pass a table variable into the nested batch with sp_executesql just like you pass one to a stored procedure, but it has to be marked readonly, and so you can't modify it.
You can see and modify existing temporary tables in nested batches, eg
drop table if exists table1
go
create table table1
(
StartDate DATETIME,
EndDate DATETIME,
Amount MONEY,
AccountId INT
)
insert into table1 values (getdate(),getdate(),1,1)
go
CREATE OR ALTER PROCEDURE EvalClearingNetSpend
AS
BEGIN
create table #t(
StartDate DATETIME,
EndDate DATETIME,
Amount MONEY,
AccountId INT)
Declare #Sql as NVARCHAR(MAX);
SET #Sql = 'INSERT INTO #T SELECT StartDate,EndDate,Amount, AccountId FROM table1';
EXEC sp_executesql #Sql
SELECT * FROM #T
END
go
exec EvalClearingNetSpend
outputs
StartDate EndDate Amount AccountId
----------------------- ----------------------- --------------------- -----------
2021-03-30 08:48:32.350 2021-03-30 08:48:32.350 1.00 1
This is an XY Problem. There is no need for the level of complexity you have put in the procedure. The table TYPE, the call to sys.sp_executesql, none of it is needed. Just put the SELECT statement of your "dynamic" query (it's not dynamic, as there's no object injection) in your Procedure:
CREATE PROCEDURE attributevalues.EvalClearingNetSpend AS --Removed sp_ prefix
BEGIN
SELECT StartDate,EndDate,Amount, AccountId FROM table1;
END;
GO
This completely avoids the error, that you are trying to use a table TYPE as an OUTPUT parameter, because you can't, but you don't need one here.
Not sure why you would go through the trouble of creating a Table Type parameter and populating it inside your from and then selecting from it. But lets say you do have to do this for some reason.
You can achieve this by doing this, no need to use output parameters at all, output parameter is used to return a scalar value, here you are getting a table back and then selecting from it:
CREATE PROCEDURE usp_EvalClearingNetSpend
AS
BEGIN
Declare #Sql as NVARCHAR(MAX);
SET #Sql = N' DECLARE #OutPutTable AS mytabletype;
INSERT INTO #OutPutTable
SELECT StartDate,EndDate,Amount, AccountId
FROM table1;
SELECT * FROM #OutPutTable
';
EXEC sp_executesql #Sql
END

Sql OpenJson - Incorrect syntax near '$.recordtype'

I have a stored procedure which i'm going to execute and the function of this is it will insert the json result in my table "ItemTransaction". Then i'm going to retrieve it by declaring variable which the JsonString. the problem is i cannot execute my stored procedure.
Incorrect syntax near '$.recordtype'.
I don't know which exactly the error.
exec AWSLINK.APILINK.dbo.spu_JsonSendData 'LoadItem',#pBranchCode,#pTranNo,'','','Test','POST'
Declare #JsonString varchar(MAX) = (Select DataReceived from AWSLINK.APILINK.dbo.ItemTransaction where
DocType ='LoadItem' and BranchCode = #pBranchCode and TranNo = #pTranNo)
SELECT * FROM
OPENJSON ( #JsonString,'$."records"')
WITH (
RecordType varchar(200) '$.recordtype' ,
ItemID varchar '$.id',
ItemDetails varchar(200) '$.itemid',
Quantity int '$.locationquantityonhand'
)
Something like this
drop proc if exists dbo.TestExample;
go
create proc dbo.TestExample
#var1 int,
#json nvarchar(max) output
as
set nocount on;
select #json=(select #var1 var1 for json path, without_array_wrapper);
go
declare
#out_json nvarchar(max);
exec dbo.TestExample 1, #json=#out_json output;
print (#out_json);
Output:
{"var1":1}

Stored procedured doesnt give the result back

I have written such a stored procedure, it must return a result, but it doesnt do that. it returns only a message that stored procedure runs successfully.
How should I change my SP?
CREATE PROCEDURE TestTVP
(
#param1 int,
#param2 int,
#a int OUTPUT
)
as
SET NOCOUNT ON
DECLARE #T1 as TABLE
(
PK INT IDENTITY NOT NULL,
Wert INTEGER,
Name INTEGER
)
INSERT INTO #T1(Wert,Name) VALUES (#param1,#param2)
return select count(*) from #T1
GO
exec TestTVP '1','22'
you have to pass OUTPUT parameter
declare #z int
exec TestTVP '1','22' ,#z output
and remove return from Stored Procedure make it only
...
select count(*) from #T1
You can use out parameter if you want the output :
DECLARE #Z int
EXEC TestTVP '2', '22',#z out

Using a variable to represent multiple values

I have the following part of a query:
Where id in (1,2,3) And country in('France','Italy','Spain')
I want to declare 2 variables and do it like:
Where id in (idsVaraible) And country in(countriesVriable)
It is more like substituting sql code in sql code to make my long query readable and more useful, is there any way to do this?
I think it's more like eval in java script.
Well if you need to pass these sets in as strings, one way would be dynamic SQL:
DECLARE #ids VARCHAR(32) = '1,2,3';
DECLARE #countries VARCHAR(2000) = 'France,Italy,Spain';
DECLARE #sql NVARCHAR(MAX) = N'SELECT ... FROM ...
WHERE id IN (' + #ids + ') AND country IN ('''
+ REPLACE(#countries, ',',''',''') + ''');';
PRINT #sql;
-- EXEC sp_executesql #sql;
Another way would be table-valued parameters. First create these types in your database:
CREATE TYPE dbo.TVPids AS TABLE(ID INT);
CREATE TYPE dbo.TVPcountries AS TABLE(Country VARCHAR(255));
Now your stored procedure can take these types as input:
CREATE PROCEDURE dbo.whatever
#i dbo.TVPids READONLY,
#c dbo.TVPcountries READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT ... FROM dbo.yourtable AS t
INNER JOIN #i AS i ON i.ID = t.ID
INNER JOIN #c AS c ON c.country = t.country;
END
GO
Now your app can pass these two parameters in as sets (e.g. from a DataTable) instead of building a comma-separated string or handling multiple parameters.
Please try using temp table variables:
DECLARE #tblID as TABLE(ID INT)
DECLARE #tblCountry as TABLE(Country NVARCHAR(50))
INSERT INTO #tblID VALUES (1),(2),(3)
INSERT INTO #tblCountry VALUES ('France'),('Italy'),('Spain')
WHERE id in (select ID from #tblID) And country in(select Country from #tblCountry)

How to make table dynamic in sql

Does anyone know how to write a script in stored proc to run the table based on the variable (or will it possible to do so?)?
for example:
I have 3 tables name called customer, supplier, and support
when user input 1, then run table customer, 2 table supplier and 3 table support
declare #input int;
if #input =1
begin
declare #table varchar(50); set #table = 'customer'
end
if #input =2
begin
declare #table varchar(50); set #table = 'supplier '
end
if #input =3
begin
declare #table varchar(50); set #table = 'support'
end
select *
INTO ##test
from #table
IF it really is that simple, why not just repeat the Select?
if #input =1
begin
Select * INTO ##test From customer
end
if #input =2
begin
Select * INTO ##test From supplier
end
if #input =3
begin
Select * INTO ##test From support
end
yes you can do it by using dynamic sql "EXEC" or by "Sp_Executesql" command.
Example :
USE Northwind
GO
CREATE TABLE #MyTemp
( RowID int IDENTITY,
LastName varchar(20)
)
DECLARE #SQL nvarchar(250)
SET #SQL = 'INSERT INTO #MyTemp SELECT LastName FROM Employees;'
EXECUTE sp_executesql #SQL
Why do you want to do this? It seems like a bad idea at first glance.
Can you post what your stored procedure is doing and any relevant tables? I suspect that you may be able to either:
Modify your schema in such a way
that you would no longer to do
this
Create different stored procedures
to do what you want on each table instead of forcing it into one proc.
There are several issues that come up when you use dynamic SQL that you should be aware of. Here is a fairly comprehensive article on the pros and cons.