How can I execute saved query statement in table in SQL Server - sql-server

INSERT #Table
SELECT 'A','DECLARE #C INT = 1 SELECT #C+1'
UNION
SELECT 'B','DECLARE #C INT = 5 SELECT #C+6'
SELECT *
FROM #Table

I think you want to run column B query..
declare #Table as table(a varchar(100),b varchar(500))
INSERT #Table
SELECT 'A','DECLARE #C INT = 1 SELECT #C+1'
UNION
SELECT 'B','DECLARE #C INT = 5 SELECT #C+6'
DECLARE #VAR VARCHAR(500)
SET #VAR=(SELECT B FROM #Table WHERE A='A')
PRINT #VAR
EXEC (#VAR)

So you are trying to store the queries in your table and then dynamically call them based on some conditions. then you would want to execute those queries. the below code must work.
create table #table (
rowcnt int identity (1,1),
value1 varchar(10),
query1 varchar(8000))
declare #query varchar(8000);
INSERT #Table
SELECT 'A','DECLARE #C INT = 1 SELECT #C+1'
UNION
SELECT 'B','DECLARE #C INT = 5 SELECT #C+6'
select #query = query1 from #table where id =1
exec (#query)
Please note storing scripts in tables and then calling them is not a good practices.
As if the Stored procedure which will call this scripts ever hit any problems it would be a nightmare for debugging it. Also it would be tough for performing performance optimization on DB.
Note if you would need to concat multiple rows for getting the full query use the below code
select #query = COALESCE(#query,'') +query1 from #table where id =1

Related

Convert stored procedure which uses exec to populate table to scalar-valued function

I have this stored procedure:
ALTER procedure [dbo].[sp_checker2]
(#Item varchar(70), #location varchar(8))
as
declare #Query varchar(2000)
set #location = 'XXX909'
declare #Table Table (Qty int)
set #Query = 'select TOP 1 * from openquery(xxxx,''SELECT NVL(b.t$st,0) from server.XXXXXID0001 a left join
server.XXXXXID0002 b on a.t$item = b.t$item where b.t$cloc = '''''+ #location + ''''' and trim(a.t$item)='''''+ #Item + ''''''')'
insert into #Table exec (#Query)
if not exists (select * from #Table )
begin
set #Query = 'select TOP 1 * from openquery(xxxx,''SELECT NVL(b.t$st,0) from server.XXXXXID0001 a
left join server.XXXXXID0002 b on a.t$item = b.t$item where trim(a.t$item) = '''''+ #Item + ''''''' )'
insert into #Table exec (#Query)
end
select * from #Table
The thing is I am looking to a query SELECT like this:
SELECT
column1, column2, column3, column4,
(EXEC [dbo].[sp_checker2] 'param1=value of column3', 'param2=another value') AS column5
FROM
table
WHERE
column1 = 'data1'
AND column2 = 'data2'
ORDER BY
column3
I know it is not possible to execute a stored procedure in a SELECT statement in SQL Server and the alternative I have is to convert the stored procedure to a function, but inside the stored procedure I have an exec to insert data into the table variable. Is there a way I can convert this stored procedure to a function ?
P.S. I only save one row in the variable table, ie: if item exists it saves its inventory: "6500"
It is difficult. In a function it is not possible to execute dynamic SQL. I think it is only possible if the WHERE criteria are shifted. You'll be better able to evaluate what impact this has on the performance.
CREATE FUNCTION [dbo].[f_checker2] (#item varchar(70),
#location varchar(8))
RETURNS #result TABLE (
Qty int
)
AS
BEGIN
INSERT
INTO #result
select TOP(1) qty
from openquery(xxxx, 'SELECT NVL(b.t$st,0) AS qty,
b.t$cloc AS location,
trim(a.t$item) AS item
from server.XXXXXID0001 a
left join server.XXXXXID0002 b
on a.t$item = b.t$item')
where location = #location
and item = #item
if not exists (select * from #result)
INSERT
INTO #result
select TOP(1) qty
from openquery(xxxx, 'SELECT NVL(b.t$st,0) AS qty,
b.t$cloc AS location,
trim(a.t$item) AS item
from server.XXXXXID0001 a
left join server.XXXXXID0002 b
on a.t$item = b.t$item')
where item = #item
RETURN
END
GO

SQL Server : select where with multiple values

I need to create a stored procedure that can check for all records matching an indefinite number of values.
So for example take the following simple statement;
SELECT *
FROM some_table
WHERE ID = #param1
However, #param1 should be able to take a string of comma-delimited values and check against all of them eg:
#param1 = '1,2,45,16,476,324,'
I imagine this would need to take the values and then turn them into a temporary table, and then somehow create a sub query to check against all the values in the temporary table. However my T-SQL skills aren't quite up to tackling that on my own just yet.
How can I do this, or is there a better way to do it?
There are many split function version online, if you just google SQL Server Split function you will get 100s of results back.
A quick fix without a function would look something like......
DECLARE #param1 VARCHAR(100) = '1,2,45,16,476,324'
DECLARE #param1XML xml;
SELECT #param1XML = CONVERT(xml,' <root> <s>'
+ REPLACE(#param1, ',','</s> <s>')
+ '</s> </root> ')
SELECT *
FROM some_table
WHERE ID IN (
SELECT T.c.value('.','varchar(20)') AS Value
FROM #param1XML.nodes('/root/s') T(c)
)
Procedure
A proc would look something like...
CREATE PROCEDURE dbo.usp_SomeProc
#param1 VARCHAR(100)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #param1XML xml;
SELECT #param1XML = CONVERT(xml,' <root> <s>'
+ REPLACE(#param1, ',','</s> <s>')
+ '</s> </root> ')
SELECT *
FROM some_table
WHERE ID IN (
SELECT T.c.value('.','varchar(20)') AS Value
FROM #param1XML.nodes('/root/s') T(c))
END
What about this solution - using XML query.
Table variable in procedure is created for test only.
CREATE PROCEDURE dbo.spTestDelimitedParam
(
#param1 as varchar(max)
)
AS
BEGIN
DECLARE #xml as xml
DECLARE #delimiter as char(1)
DECLARE #test table (id int, description varchar(20))
insert into #test
values (1, 'Row ID = 1'), (11, 'Row ID = 11'), (3, 'Row ID = 3')
SET #delimiter =','
SET #xml = cast(('<X>'+replace(#param1,#delimiter ,'</X><X>')+'</X>') as xml)
SELECT *
FROM #test
WHERE ID IN (SELECT N.value('.', 'int') as value FROM #xml.nodes('X') as T(N))
END
How it works:
exec dbo.spTestDelimitedParam '1,23,4,11,24456'

Selecting one column among many returned by stored procedure in sql server

I have a stored procedure which returns several number of columns. What I want to do is select only one column from the stored procedure returned data.
I tried with creating a temp table and inserting data from stored procedure to that temp table, but I'm getting errors.
What I want is something like this.
select p_name from Exec sp_getPatientData
where sp_getPatientData returns multiple columns.
can someone help me with it.
If you have this store procedure like this:
CREATE PROCEDURE spTest
AS
BEGIN
SELECT 1 AS column1,'2' AS column2
END
GO
Then you could do this:
DECLARE #tbl TABLE(column1 INT,column2 VARCHAR(100))
INSERT INTO #tbl
EXEC spTest
SELECT column1 FROM #tbl
Update:
You have a problem in the syntax:
SET NOCOUNT ON;
DECLARE tabl1 TABLE (Session_n int, patient_n int, initialName varchar(50),
nodeValue varchar(50), diagCode varchar(50));
INSERT INTO tbl1
EXEC SP_PATIENTALERTS
SELECT PATIENT_N FROM tbl1 WHERE PATIENT_N = 12345
this part:
INSERT INTO tbl1
EXEC SP_PATIENTALERTS
SELECT PATIENT_N FROM tbl1 WHERE PATIENT_N = 12345
I think. Should be like this:
INSERT INTO tabl1
EXEC SP_PATIENTALERTS
SELECT PATIENT_N FROM tabl1 WHERE PATIENT_N = 12345
I got the problem and solution also.
SP is
Create PROCEDURE spTest1
AS
BEGIN
if object_id('TEMPDB..#tbl1') is not null
drop table #tbl1
CREATE TABLE #tbl1 (column1 INT,column2 VARCHAR(100) )
DECLARE #sql nvarchar(max) = 'INSERT INTO #tbl1
SELECT 111 AS column1,''2222'' AS column2
Union all
SELECT 221 AS column1,''2211'' AS column2'
insert into #tbl1
EXEC SP_EXECUTESQL #sql
select column1,column2 from #tbl1
END
GO
and query is
SET NOCOUNT ON
DECLARE #tbl TABLE(column1 INT,column2 VARCHAR(100))
INSERT INTO #tbl
EXEC spTest1
SELECT column1 FROM #tbl
Error generated
Msg 8164, Level 16, State 1, Procedure spTest1, Line 31
An INSERT EXEC statement cannot be nested.
Solution:
You cannot use insert when there is nested EXEC. i just removed the string query from store procedure and used direct select query. Problem was solved.

Querying multiple tables in TSQL where table name comes from another table

I need to select from table where the the table name suffix are from another table, like this :
declare #value nvarchar(3),
#table nvarchar(1000),
#SQLST NVARCHAR(255);
set #value = N'select column1 from tableX';
EXEC #value
set #table ='partoftableY'
Set #SQLST ='select * from' +#tabel + #value -- here I create the table name
However there are multiple values in TableX (0-999) and so this doesn't work. Do I need a For Each type construct.
here in an example I created with two tables (partoftableY1 & partoftableY2) with different data in each
/*
create table tableX (column1 int);
insert into tablex
select 1
union all select 2;
create table partoftableY1 (data nvarchar(50));
create table partoftableY2 (data nvarchar(50));
insert into partoftableY1 select 'hey 1 here';
insert into partoftableY2 select 'hey 2 here';
*/
declare #sql nvarchar(max)
-- use the ability of SQL to build up string of all the sql you need to run
set #sql = 'select data from (select '''' as data'
select #sql = COALESCE(#sql + ' union all ', '')
+ 'select data from partoftableY'
+ cast(column1 as nvarchar(4)) from tableX
select #sql = #sql + ') X where data <>'''''
-- DEBUG for seeing what SQL you created
print #sql
-- Now execute the SQL
exec sp_executesql #sql= #sql
which gives me the results of
hey 1 here
hey 2 here
You will need to adjust it for types of your data, but this should give you the main idea
For reference here is the sql that was created and executed:
select data
from (
select '' as data
union all select data from partoftableY1
union all select data from partoftableY2
) X
where data <>''
N.B.
I put formatted it for easier reading, as it's actually created as one long line
I used selet data and not select * as the number of columns needs to be the same for each select in the union. You will need to select the columns you need and then make changes ensure that all the columns in the selects in the union are the same.
There is a dummy select at the top of the union to make the union code easy - no conditionals needed as whether the union all needs to present
I used the out select over the whole union to enable you to get sid of the dummy select
You can try this
DECLARE #SQLST NVARCHAR(max)='';
DECLARE #select nvarchar(max)=N'select * from partoftableY'
DECLARE #union nvarchar(max)=N'
UNION ALL
'
SELECT #SQLST=#select+column1+#union
FROM tablex
SELECT #SQLST=substring(#SQLST,1,LEN(#SQLST)-11)
EXEC sp_executesql #SQLST

SQL Output contents of a table to string

I have a table that contains many rows of SQL commands that make up a single SQL statement (to which I am grateful for this answer, step 5 here)
I have followed the example in this answer and now have a table of SQL - each row is a line of SQL that build a query. I can copy and paste the contents of this table into a new query window and get the results however due to my lack of SQL knowledge I am not sure how I go about copying the contents of the table into a string variable which I can then execute.
Edit: The SQL statement in my table comprises of 1 row per each line of the statement i.e.
Row1: SELECT * FROM myTable
Row2: WHERE
Row3: col = #value
This statement if copied into a VARCHAR(MAX) exceeds the MAX limit.
I look forward to your replies. in the mean time I will try myself.
Thank you
You can use coalesce to concatenate the contents of a column into a string, e.g.
create table foo (sql varchar (max));
insert foo (sql) values ('select name from sys.objects')
insert foo (sql) values ('select name from sys.indexes')
declare #sql_output varchar (max)
set #sql_output = '' -- NULL + '' = NULL, so we need to have a seed
select #sql_output = -- string to avoid losing the first line.
coalesce (#sql_output + sql + char (10), '')
from foo
print #sql_output
Note: untested, just off the top of my head, but a working example of this should produce the following output:
select name from sys.objects
select name from sys.indexes
You can then execute the contents of the string with exec (#sql_output) or sp_executesql.
You can try something like this
DECLARE #TABLE TABLE(
SqlString VARCHAR(MAX)
)
INSERT INTO #TABLE (SqlString) SELECT 'SELECT 1'
DECLARE #SqlString VARCHAR(MAX)
SELECT TOP 1 #SqlString = SqlString FROM #TABLE
EXEC (#SqlString)
Concatenate string from multiple rows
DECLARE #Table TABLE(
ID INT,
Val VARCHAR(50)
)
INSERT INTO #Table (ID,Val) SELECT 1, 'SELECT *'
INSERT INTO #Table (ID,Val) SELECT 2, 'FROM YourTable'
INSERT INTO #Table (ID,Val) SELECT 3, 'WHERE 1 = 1'
DECLARE #SqlString VARCHAR(MAX)
--Concat
SELECT DISTINCT
#SqlString =
(
SELECT tIn.Val + ' '
FROM #Table tIn
ORDER BY ID
FOR XML PATH('')
)
FROM #Table t
PRINT #SqlString
if you want to execute a string of sql then use Exec() or sp_executeSql

Resources