SQL Server : select from stored procedure - sql-server

Currently, this is the only way I know
Create #tempTable1
Insert into #tempTable1
Exec mySP1 input1, input2
Create #tempTable2
Insert into #tempTable2
Exec mySP2 input1, input2
Select *
from #tempTable1 as A
join #tempTable2 as B on A.input1 = B.input1
Which is very inconvenient because first I would have to create barebone temp tables then insert into, once finished I must remove temp tables. Is there a better way to for me to do something like this instead?
Select *
from (Exec mySP1 input1, input2) as A
join (Exec mySP2 input1, input2) as B on A.input1 = B.input1

https://blog.sqlauthority.com/2022/02/08/sql-server-using-stored-procedure-in-select-statement/
Not sure why this blog didn't show up at work today but I'm going to print this out and try it out on Monday.
SELECT *
FROM OPENROWSET('SQLNCLI',
'server=localhost;trusted_connection=yes;',
'EXEC Exec mySP1 input1, input2') as A
join
OPENROWSET('SQLNCLI',
'server=localhost;trusted_connection=yes;',
'EXEC Exec mySP2 input1, input2') as B on A.input1 = B.input1
Any comment ?

Related

Use a stored procedure in IF EXISTS method instead of select statement

I would love to reuse a stored procedure in this situation instead of rewriting the code
IF EXISTS (EXEC [dbo].[SP_JobStop_FindJobByAll] WITH (updlock,serializable)
--IF EXISTS (SELECT * FROM [EZPassDataDB].[dbo].[JobPass] AS [o] WITH (updlock,serializable)
--WHERE [o].[jobNumber] = #jobNumber
You can load the resultset from the stored procedure into a temp table or table variable with INSERT ... EXEC, eg:
declare #jobs table(...)
insert into #jobs(...)
exec [dbo].[SP_JobStop_FindJobByAll]
if exists (select * from #jobs)
begin
. . .
end

How to pass an array of integer values from a table to a stored procedure?

I have a stored proc using dynamic sql that updates a few columns based on the value passed to it. I am trying to test it out for multiple values without having to enter those manually. These values are to be taken from a table. Is there a way to pass all these values in the table and have it go through the proc? Just like in your regular programming language where you would run through an array. I am doing this in sql server 2012.
Code is something like this
CREATE PROCEDURE sp1 #enteredvalue int
AS
BEGIN
UPDATE table1
SET column1 = 'some var char value',
column2 = 'some integer values'
WHERE xid = #enteredvalue
END
I want to enter the values for that integer parameter (#enteredvalue) from a table that has different values.
Perhaps a little more dynamic SQL will do the trick (along with a parser)
Declare #String varchar(max) = '1,25,659'
Declare #SQL varchar(max) = ''
Select #SQL = #SQL + concat('Exec [dbo].[sp1] ',Key_Value,';',char(13))
From (Select * from [dbo].[udf-Str-Parse-8K](#String,',')) A
Select #SQL
--Exec(#SQL)
Returns
Exec [dbo].[sp1] 1;
Exec [dbo].[sp1] 25;
Exec [dbo].[sp1] 659;
The UDF if needed (super fast!)
CREATE FUNCTION [dbo].[udf-Str-Parse-8K](#String varchar(8000), #Delimiter varchar(50))
Returns Table
As
--Usage: Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',')
-- Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||')
-- Select * from [dbo].[udf-Str-Parse-8K]('The quick brown fox',' ')
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(#String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 a, cte1 b, cte1 c, cte1 d) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(#Delimiter) From cte2 t Where Substring(#String,t.N,DataLength(#Delimiter)) = #Delimiter),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(#Delimiter,#String,s.N),0)-S.N,8000) From cte3 S)
Select Key_PS = Row_Number() over (Order By A.N)
,Key_Value = Substring(#String, A.N, A.L)
,Key_Pos = A.N
From cte4 A
)
Another approach is (without Dynamic SQL):
1) Create a new SP where input parameter is a table
https://msdn.microsoft.com/en-us/library/bb510489.aspx
2) In that procedure, create a WHILE loop to go through each row and execute your existing SP for each individual row value
Example of WHILE loop is here:
SQL Call Stored Procedure for each Row without using a cursor
To pass a table into an SP, consider creating a User-Defined Table type. Example:
create type ArrayOfInt as table (IntVal int)
go
create proc SumArray(#IntArray ArrayOfInt readonly)
as
select sum(IntVal) from #IntArray
go
declare #IntArray ArrayOfInt
insert #IntArray values (1), (2), (3)
select * from #IntArray
exec SumArray #IntArray
drop proc SumArray
drop type ArrayOfInt

Select (Select field from FieldTable) from Table

I'm using MSQL 2005. I have 2 table.A and B
Table A
- ID DOVKOD
- 1 KURSATIS
Table B
- ID KURALIS KURSATIS
- 1 2,2522 2,2685
- 2 2,4758 2,4874
Table A has only 1 record
When I execute Select (Select DOVKOD from Table A) from Table B I want to get same result as Select KURSATIS from Table B
I am gonna use it in a view. How can I do that. Thanks..
You can simply use a CASE expression:
SELECT CASE WHEN (SELECT DOVKOD FROM A) = 'KURSATIS' THEN KURSATIS
ELSE KURALIS
END
FROM B
SQL Fiddle Demo here
You must use Dynamic TSQL
SELECT #column=DOVKOD from Table A
EXEC ('Select ' + #column + ' from Table B')
If I understood you right then in table A you have the name of the column that you want to return. Then your solution is bad at all. I'll rather do something like that:
CREATE TABLE #TableA
(
ID INT, DOVKOD VARCHAR(100)
);
INSERT INTO #TableA VALUES (1, 'KURSATIS');
CREATE TABLE #TableB
(
ID INT, Value DECIMAL (18,2),Name VARCHAR(100)
);
INSERT INTO #TableB VALUES (1, 2.2522 , 'KURALIS');
INSERT INTO #TableB VALUES (2, 2.4758 , 'KURSATIS');
SELECT #TableB.* FROM #TableB JOIN #TableA ON #TableA.DOVKOD = #TableB.Name
The only way how to do this in MySQL is using Prepared statements. Dynamic pivot tables (transform rows to columns) is a good article about this.
SET #sql = NULL;
Select DOVKOD INTO #sql
FROM from Table A;
SET #sql = CONCAT('SELECT ', #sql, 'FROM Table B');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Is it possible to use a stored procedure to update three different tables?

I have an proc doing a select and update statements as follows. I need to incorporate the update statements and select statement which put the data into a temp table into a single sql select statement.
Is this possible?
'
Yes:
CREATE TABLE TableA
(
valueA int
)
INSERT INTO
TableA
VALUES
(1),
(2),
(3)
GO
CREATE PROCEDURE test_procedure (#in_value int)
AS
BEGIN
--insert into temp table
SELECT
#in_value [out_value]
INTO
#TestTable
-- update with join on temp table
UPDATE
T
SET
T.[out_value] = 2
FROM
#TestTable T
INNER JOIN TableA A on A.valueA = T.out_value
WHERE
A.valueA = 1
-- update with join on temp table again
UPDATE
T
SET
[out_value] = 3
FROM
#TestTable T
INNER JOIN TableA A on A.valueA = T.out_value
WHERE
A.valueA = 2
--select results including the original "in_value"
SELECT
*,
#in_value [in_value]
FROM
TableA A
LEFT JOIN #TestTable T on T.out_value = A.valueA
END;
GO
--execute stored procedure
EXEC test_procedure 1
I have found one way out by using union.
this is bit wierd but since i am not able to find anything else, settled with this method

Scope of #TempTables limited to an EXEC statement?

By trying this
use master
go
select * into #TempTable from sys.all_views
select * from #TempTable
drop table #TempTable
exec('
select * into #TempTable2 from sys.all_views
')
/* This will give error: */
select * from #TempTable2
I realized that #TempTable2 is not accessible... so using the select into #TempTable syntax is used inside an EXEC statement means the table is auto destroyed as the exec statement is completed?
Yes.
You can see this with
exec('
select * into #TempTable2 from sys.all_views
select * from tempdb.sys.tables
')
select * from tempdb.sys.tables
You can use a ##global temporary table if you want to be able to access it later. e.g.
use master
go
declare #temptablename char(40)
set #temptablename = '[##' + cast(newid() as char(36)) + ']'
exec('
select * into ' + #temptablename + ' from sys.all_views
')
/* Do some other stuff: */
exec('
select * from ' + #temptablename)
You could create a global temp table
create table ##TempTable (
/* Structure goes here */
)
exec('insert into ##TempTable(/*Columns*/) select * from sys.all_views')
select * from ##TempTable
(If you do this, and your code might be used by multiple users, then include a SPID column in the temp table, include ##SPID in the select list, and change the final select to filter by SPID = ##SPID)
Yes you are correct. The temp table within the Exec statement is only accessible within that statement.
If you open two windows in SSMS and create a temp table in one window you won't be able to access it through the other window as it is a different connection.
However, you will be able to access it if you create a global temp table. Global temp tables are defined with a double ## instead of one.
There is an article here from SQLTeam regarding temp tables and also here from MSDN

Resources