combine two T-SQL in a dynamic way - sql-server

How can I using something like if or case..when to combine the following code into one?
if #para = 'test'
begin
select * from Table A where status='A' and id in (select id from Table B)
end
else if #para = 'others'
begin
select * from Table A where status='A' and id in (select id from Table c)
end
like select * from Table A where id in if #para = XXX then (select id from Table B)
Thanks a lot.

Try this:
select *
from Table A
where (id in (select id from Table B) and #para = 'test')
OR
(id in (select id from Table c) and #para = 'others')

As you tagged stored procedure i made it as one ... try it like this
create procedure GetData (#para nvarchar(100))
as
begin
declare #sql nvarchar(max)
set #sql = case
when #para = 'test'
then
'Select * from TableA A
join TableB B on A.id = B.ID'
else -- if #para = 'others' goes into else
'Select * from TableA A
join TableB B on A.id = B.ID'
end
execute (#sql)
end

Related

How to add rows with null data dynamically in result table in SQL Server 2012?

I have this table with 22 rows as above
I am getting a converted table as above
I created following procedure in order to get result table
ALTER PROCEDURE [dbo].[proc_YS_BAB_IR_Item]
#UserId int
AS
BEGIN TRAN
DECLARE #SqlQry NVARCHAR(MAX);
SET #SqlQry = N''
DECLARE #Cnt INT = 1, #EndCnt INT = 25,
#v_UserId INT = CAST(#UserId AS VARCHAR(MAX));
CREATE TABLE #TempColumns
(
Calculate_ItemIdentifier VARCHAR(MAX),
SeqOrder INT
)
WHILE #cnt <= #EndCnt
BEGIN
INSERT INTO #TempColumns
SELECT
'IR'+ CAST(#Cnt AS VARCHAR(MAX)),
#Cnt
SET #Cnt = #Cnt + 1;
END
DECLARE #DATA VARCHAR(10), #DATA1 VARCHAR(10) = '000000'
DECLARE #zero_str VARCHAR(6) = '000000'
-- Generate table alike to yours
DECLARE #yourTable TABLE ([value] varchar(max))
-- convert array to xml
;WITH cte AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn,
[response],
CAST('<a>'+REPLACE(SUBSTRING([response],2,LEN([response]) - 2),',','</a><a>')+'</a>' as xml) AS x,
#v_UserId AS UserId,
[item_identifier]
FROM
#TempColumns
LEFT JOIN
YS_BAB_response_dump ON YS_BAB_response_dump.Item_Identifier = #TempColumns.Calculate_ItemIdentifier
AND UserId = CAST(#UserId AS VARCHAR(MAX))
AND TestModel = 'IR'
)
-- do the stuff
SELECT
c.rn,
c.[response],
c.[item_identifier],
RIGHT(#zero_str +
CAST(SUM(CAST(STUFF(#zero_str,t.c.value('.','tinyint')+1,1,'1') AS INT)) AS VARCHAR(6)), 6) AS ans,
c.UserId
FROM
cte c
CROSS APPLY
x.nodes('/a') AS t(c)
GROUP BY
c.rn, c.[response], c.UserId, c.[Item_Identifier]
ORDER BY
c.rn
COMMIT TRAN
What changes I need to do in above procedure to get 25 records as a result instead of 22, For IR21,IR22 and IR25 I want null data in response and ans columns for that respective userId? May i need to use some other function instead of CROSS APPLY? How it will be?
You were almost there. Use OUTER APPLY instead of CROSS APPLY

How to insert value into a SQL Server table by getting value and column name from another table

create table T1
(
Name varchar(50),
Address varchar(50),
Tel varchar(50)
);
create table T2
(
ParamName varchar(50),
ParamValue Varchar(60),
TableName varchar(50)
);
insert into T2 values('Name', 'test', 'Member');
insert into T2 values('Address', 'testAdd', 'Member');
insert into T2 values('Tel', 'test', 'Member');
insert into T1(Select distinct ParamName from T2)
values(select ParamValue from T2 )
I'm looking for a way to do a insertion to T1 table by getting value and column name from T2 table.need to get column name from T2 table and Value to that particular column
You can use this:
INSERT INTO T2(Column1,Column2)
SELECT Column1, Column2 FROM T1
GROUP BY Column1;
You could try using a pivot query on T2 to get the names, addresses, and telephone numbers onto a single row for each table name. Then, just do an INSERT INTO ... SELECT as you were, except use the pivoted result.
INSERT INTO T1 (Name, Address, Tel)
SELECT
MAX(CASE WHEN ParamName = 'Name' THEN ParamValue END) AS Name,
MAX(CASE WHEN ParamName = 'Address' THEN ParamValue END) AS Address,
MAX(CASE WHEN ParamName = 'Tel' THEN ParamValue END) AS Tel
FROM T2
GROUP BY TableName
-- WHERE TableName IN ('Member', ...)
You can uncomment the WHERE clause if you want to restrict the insert to certain table names.
As a general comment, if you are doing this to get your data into a more normalized form, then I think it is good. But if you plan on storing your data like this long term, you might want to reconsider your table design.
Your table structure doesn't make much sense. There is no obvious logical relation between the tables. Is the second one just a buffer table?
In any case however, if you want to insert values from a table into another table you do it like that:
INSERT INTO [target_table] ([target_column_1], [target_column_2], ..., [target_column_n])
SELECT [source_column_1], [source_column_2], ..., [source_column_n]
FROM [source_table]
WHERE [conditon]
I think you are looking like..
INSERT INTO T1(Name)
SELECT DISTINCT ParamName FROM T2
DECLARE #TableName varchar(50) = 'T1'
DECLARE #ColumnName varchar(MAX)
SELECT #ColumnName= coalesce(#ColumnName + ', ', '') + a.COLUMN_NAME
from (SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
inner join T2 on TableName = TABLE_NAME
WHERE TABLE_NAME = #TableName and ParamName = COLUMN_NAME) a;
print #ColumnName
declare #ParamName varchar(MAX)
SELECT #ParamName = coalesce(#ParamName + ', ', '') + ''''+a.ParamValue+''''
from (SELECT COLUMN_NAME,ParamValue
FROM INFORMATION_SCHEMA.COLUMNS
inner join T2 on TableName = TABLE_NAME
WHERE TABLE_NAME = #TableName and ParamName = COLUMN_NAME) a;
print #ParamName
declare #QUERY nvarchar(MAX);
SET #QUERY = 'INSERT INTO T1 ('+#ColumnName+')
VALUES ('+#ParamName+')'
EXEC sp_executesql #QUERY
this is the answer what i expect ,thanks all for your help

SSRS page splitting

So I am performing a while loop on 3 stored procs and inserting the data into temp tables and then performing a union on them and when I run the query It returns 10 results but when I make a report out of it in SSRS it returns just the first result and stops! shouldn't it make multiple pages with the other results?
declare #temptable table ( id int )
while (select count(*) from customerid c left join #temptable t on c.id = t.id where t.id is null) > 0 begin
insert into #temptable select min(c.id) from customerid c left join #temptable t on c.id = t.id where t.id is null
declare #id2 varchar(50) = (select max(id) from #temptable)
-- insert into temp tables here
exec DoctorsSDJs #id = #id2
-- insert into temp table
exec LocationSDJs #id = #id2
-- insert into temp tables
exec PatientSDJs #id = #id2
-- performing my union on the 3 tables
end

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 : indexing for table and columns

I have a table where I am storing all tables name and column name, now I want to get data according to that table with different conditions.
I will use one single query column name and table name will take dynamically from this table and than I will use in select query and will get data from respective column and table.
Table name is ADE_ColumnIndexing
In this table I have all table names as TableName column, and column names as name column...
Now I want to use
select fieldname
from tablename
where Id = newdata
This query will return data of that column and table... I mean tablename = ade_log and columnname = history...
So my query will be select history from ade_log... Is it possible?
It's possible to build and execute dynamic sql, though it doesn't seem like a good aproach:
DECLARE #Sql varchar(max)
SELECT #Sql = 'SELECT '+ ColumnName +
' FROM '+ TableName +
' WHERE Id = '+ IdValue
FROM ADE_ColumnIndexing
WHERE TableName = #TableName
AND ColumnName = #ColumnName
EXEC(#Sql)
I think if you use the ID column for search, definitely not recommended as it may seem to me, the IDVal is auto-increment (correct me if i'm wrong). So why not use
exec('select [' + #column_name + '] from [' + #tablename + ']');
if you want an added validation if the table or column exists, you may query in sys.
if (
select
COUNT(*)
from sys.tables tb
left join sys.columns c
on
tb.object_id = c.object_id
where
tb.name = #tablename
and c.name = #columnname
) != 0
begin
exec('select [' + #column_name + '] from [' + #tablename + ']');
end
else
begin
select 'table or column does not exist'
end
EDIT : Seems like your table has "queries" as a row, then see my simple script below if I understand you correctly....(hopefully)
CREATE TABLE test (qry nvarchar(4000)) -- test query table
CREATE TABLE test1 (sales decimal(18,2)) -- sales table
INSERT INTO test1 (sales) -- dummy records for sales table
values (5923.59), (5923.52),(5923.51)
INSERT INTO test (qry) -- dummy records for query table
values ('select * from test1 where sales = 5923.59')
,('select * from test1 where sales = 5923.52')
,('select * from test1 where sales = 5923.51')
declare #myqry nvarchar(4000) = (SELECT qry + '; ' AS [text()] FROM test FOR XML PATH('')) -- from records to 1 query statement with multiple table results
declare #myqry2 nvarchar(4000) = SUBSTRING(
(SELECT qry + ' union all ' AS [text()] FROM test FOR XML PATH(''))
,0
,LEN((SELECT qry + ' union all ' AS [text()] FROM test FOR XML PATH(''))) - 9
)
-- from records to 1 query statement with single table results
select 'my query', #myqry -- see content of #myqry
select 'my query 2', #myqry2 -- see content of #myqry2
EXEC(#myqry) -- execute #myqry
EXEC(#myqry2) -- execute #myqry2
EDIT : This is my last attempt for your case. Please try this sample code set which still uses table:[test] and table:[test1]
DECLARE #intloop INT = 1 -- variable setter for number of loops
,#qry nvarchar(4000) = '' -- variable setter for the looping query
SELECT ROW_NUMBER() OVER (ORDER BY qry) AS id, qry INTO #tmpQueries FROM [test] -- create temp table for fake 'id'
CREATE TABLE #tmpQuery (id int, qry nvarchar(4000), res nvarchar(4000)) -- table result container
CREATE TABLE #tmpInsert (res nvarchar(4000)) -- execute query container
WHILE (#intloop < (SELECT COUNT(*) FROM #tmpQueries) + 1)
BEGIN
SET #qry = (SELECT TOP 1 qry FROM #tmpQueries WHERE id = #intloop) -- get the qry base from ID
DELETE FROM #tmpInsert -- delete records of query container
INSERT INTO #tmpInsert -- insert records into query container
EXEC (#qry) -- execute qry
INSERT INTO #tmpQuery (id, qry, res)
VALUES (#intloop, #qry, (SELECT TOP 1 res FROM #tmpInsert)) -- transfer id, qry and result into #tmpQuery table
SET #intloop = #intloop + 1 -- increment record
END
SELECT * FROM #tmpQuery -- select all records in #tmpQuery table
DROP TABLE #tmpQueries
DROP TABLE #tmpQuery
DROP TABLE #tmpInsert
NEW TABLE SAMPLE STRUCT : Create identity ID's for test and test1, and specify ID inside query. (notice the select * from test1 before into select id, sales from test1)
CREATE TABLE test (id int identity(1,1), qry nvarchar(4000)) -- test query table
CREATE TABLE test1 (id int identity(1,1), sales decimal(18,2)) -- sales table
INSERT INTO test1 (sales) -- dummy records for sales table
values (5923.59), (5923.52),(5923.51)
INSERT INTO test (qry) -- dummy records for query table
values
('select id, sales from test1 where sales = 5923.59')
,('select id, sales from test1 where sales = 5923.52')
,('select id, sales from test1 where sales = 5923.51')
SIMPLIFIED SCRIPT : Assuming all ID's of test and test1 are siblings, you can simply do the query this way.
declare #myqry2 nvarchar(4000) = SUBSTRING(
(SELECT qry + ' union all ' AS [text()] FROM test FOR XML PATH(''))
,0
,LEN((SELECT qry + ' union all ' AS [text()] FROM test FOR XML PATH(''))) - 9
)
CREATE TABLE #tmpResult(id int, qry nvarchar(4000))
INSERT INTO #tmpResult
EXEC(#myqry2) -- execute #myqry2
SELECT
tr.id
, t.qry
, tr.qry AS [sales]
FROM [test] t
LEFT JOIN #tmpResult tr
ON
t.id = tr.id
DROP TABLE #tmpResult
EDIT : We can remove the substring, but as per your request, all rows must be in single table result, so "union all" can't be un-done, unless you have your own ways, that's a plus.
select
*,
case
when id = 1 then ' union all '
when id = 2 then ' union all '
else ''
end as [row_extender]
into #tmptest
from test
--drop table #tmptest
declare #myqry2 nvarchar(4000) = (SELECT qry + row_extender AS [text()] FROM #tmptest FOR XML PATH(''))
CREATE TABLE #tmpResult(id int, qry nvarchar(4000))
INSERT INTO #tmpResult
EXEC(#myqry2) -- execute #myqry2
SELECT
tr.id
, t.qry
, tr.qry AS [sales]
FROM [test] t
LEFT JOIN #tmpResult tr
ON
t.id = tr.id
DROP TABLE #tmpResult
DROP TABLE #tmptest

Resources