need to assign values from sql query in single instance - sql

I am executing the below query in sql-server-2008-R2 which gives me output as I wanted(i.e, number of rows) but, I want to store the result in form of a multi-columned row(s) in a variable.
declare #rCount int
declare #kuri nvarchar(max)
declare #IDs nvarchar(max)
select #rCount=10
set #kuri='select top '+cast(#rCount as varchar)+' FLD295,FLD9 from tableName (nolock) ORDER BY NEWID()'
execute(#kuri)
I had done this earlier but it was different query where I need to concatenate the result of both the queries in to one column (assigning and display)
select #IDs=CAST(isnull(#IDs ,'')as varchar)+CAST(COALESCE(fld9,',')as varchar) from table1307 (nolock) ORDER BY NEWID()

DECLARE #T1 TABLE (
FLD9 bigint
, FLD295 nVARCHAR(max)
)
insert into #T1(,FLD295,FLD9)
select top(#rCount) FLD295,FLD9 from tableName (nolock)
ORDER BY NEWID()
select * from #T1
select #IDs=CAST(isnull(#IDs ,'')as varchar)+CAST(COALESCE(fld9,',')as varchar) from #T1

I think you're missing the face that you can do
declare #i int=3
select top(#i) .... –
2008 does support dynamic top
I hope you know that result should be single. , otherwise , it can't be possible (unless you're doing insert into...
if you're asking about how to concatenate ( cte is jsut table , ignore it)

You can use cursor for access result set:
declare #rCount int
declare #kuri nvarchar(max)
declare #IDs nvarchar(max)
declare #FLD295 int
declare #FLD9 int
select #rCount=10
set #kuri='declare cursor curs for select top '+cast(#rCount as varchar)+' FLD295,FLD9 from tableName (nolock) ORDER BY NEWID()'
exec sp_executesql #kuri
open curs
fetch from curs
into #FLD295, #FLD9
while ##fetch_status = 0
BEGIn
fetch from curs
into #FLD295, #FLD9
END
close curs
deallocate curs

Related

Using multiple select statements inside single query and display the results as a new rows

I want to create a query which returns the sum of certain select statement parameters within the query and create a new result table with new rows which is the results derived from select statements as below.
This is my table.
I want the result to be like below where Col4 is the result of a select statement with row 2, 3 and 5 and column 5 is the result of the calculation on the col values as below
and the result will look like this below. Is that possible to do in MS SQL SERVER.
Demo
--http://sqlfiddle.com/#!18/87a6f/4
--Schema
create table mytable(col1 int,col2 int,col3 int,col4 int)
insert into mytable values
(111,1,0,4),
(112,3,1,2),
(113,1,2,2),
(114,2,4,3),
(115,3,1,0),
(116,1,0,2),
(117,2,1,0),
(118,4,1,3),
(119,3,2,1)
create table tabscript (col4 varchar(max),col5 varchar(max))
create table tabresult(col4 varchar(max),col5 int)
--Put here th scripts you wish to execute
insert into tabscript(col4,col5) values('112,113,115','sum(col2+col3+col4)'),
('115,117,119','sum(col2+col3+col4)'),('114,118,111','sum(col2+col3+col4)')
--Kamel Gazzah
--kamelgazzah#gmail.com
--29/10/2019
declare #script as varchar(max)
declare #sqlCommand as nvarchar(max)
declare #result as int
declare mycursor cursor for
select concat('select #result=',col5, ' from mytable where col1 in(',col4,')')
from tabscript
open mycursor
declare #sql as nvarchar(max)
fetch mycursor into #sqlCommand
while ##fetch_status=0
begin
--print #sql
--print #sqlCommand
exec sp_executesql #sqlCommand,N'#result int output',#result output
insert into tabresult values(#sqlcommand,#result)
fetch mycursor into #sqlCommand
end
close mycursor
deallocate mycursor
go
select * from tabresult

How to run a while loop to run a dynamic query in SQL?

How to run a while loop to run a dynamic query in SQL?
Declare #var1 nvarchar(max)
Declare #var2 nvarchar(max)
Declare #var3 nvarchar(max)
While loop ( #var1, #var2, #var3 .... )
Begin
insert into TableA
exec (#var1) .. - in the loop logic
End
If I understood well, you wan to use a loop to execute a set of dynamic SQL queries. Then you need to use a table to iterate between them,
Im using a variable table, but you can use a temp table if you prefer
DECLARE #Vars TABLE([ID] NOT NULL IDENTITY, [Var] NVARCHAR(MAX))
/*
INSERT Values to #Vars
*/
DECLARE #ID INT, #Var NVARCHAR(MAX)
WHILE EXISTS (SELECT 1 FROM #Vars)
BEGIN
SELECT TOP 1 #ID = [ID], #Var = [Var] FROM #Vars ORDER BY [ID]
INSERT TableA
EXEC(#Var)
DELETE #Vars WHERE [ID] = #ID
END

Create a dynamic query

I have made a stored procedure like this..
CREATE PROCEDURE [dbo].[sp_dataPull] #serverName nvarchar(30), #dbName nvarchar (30), #serverName2 nvarchar(30), #dbName2 nvarchar (30)
INSERT INTO sampleDatabase.dbo.WorkFlowCopy
([ServerName]
,[DBName]
,[ID]
,[ActivityDefinitionID]
,[ParentID]
,[Caption]
,[Description]
,[ShortDescription]
(SELECT #serverName, #dbName, sdb1.* from OPENDATASOURCE('SQLOLEDB',
'Data Source=phmnldb16\eaudit;user id=XXXX;password=XXXX').AUDIT_FSA_170_001.AUD170.Workflow sdb1)
UNION ALL
(SELECT #serverName2, #dbName2, sdb2.* from OPENDATASOURCE('SQLOLEDB',
'Data Source=phmnldb16\eaudit;user id=XXXX;password=XXXX').AUDIT_FSA_170_002.AUD170.Workflow sdb2)
This query's function is to move the the data from another server into specific table. Now, notice that I have 2 SELECT statements below and I have 4 parameters. It's because I combined 2 tables and moved it into another table.
The problem with this query is the fact that it is static. What If I need to combine 3 or more tables? Then I have to create another (SELECT and UNION ALL statement below and add another 2 or more parameters).. I want to make it DYNAMIC.
Try as follows:
CREATE PROCEDURE SP_DATAPULL #SERVER NVARCHAR(30),#DB NVARCHAR(30)
AS
BEGIN
DECLARE #SERVER NVARCHAR(MAX)='SERVER1,SERVER2,SERVER3,SERVER4,SERVER5'
DECLARE #DB NVARCHAR(MAX)='DB1,DB2,DB3,DB4,DB5'
DECLARE #SRV NVARCHAR(MAX),#DBN NVARCHAR(MAX),#QUERY NVARCHAR(MAX)
DECLARE #TEMP TABLE(SERVERNAME VARCHAR(100),DB VARCHAR(100))
WHILE(SELECT CHARINDEX(',',#SERVER))>0
BEGIN
SET #SRV=(SELECT SUBSTRING(#SERVER,0,CHARINDEX(',',#SERVER)))
SET #SERVER=SUBSTRING(#SERVER,LEN(#SRV)+2,LEN(#SERVER))
SET #DBN=(SELECT SUBSTRING(#DB,0,CHARINDEX(',',#DB)))
SET #DB=SUBSTRING(#DB,LEN(#DBN)+2,LEN(#DB))
INSERT INTO #TEMP VALUES (#SRV,#DBN )
END
INSERT INTO #TEMP VALUES (#SERVER,#DB )
SET #QUERY=' INSERT INTO sampleDatabase.dbo.WorkFlowCopy
([ServerName]
,[DBName]
,[ID]
,[ActivityDefinitionID]
,[ParentID]
,[Caption]
,[Description]
,[ShortDescription] '
DECLARE C CURSOR FOR
SELECT SERVERNAME,DB FROM #TEMP
OPEN C
FETCH NEXT FROM C INTO #SERVER,#DB
WHILE ##FETCH_STATUS=0
BEGIN
SET #QUERY=#QUERY+'(SELECT '''+#SERVER+''', '''+#DB+''', sdb1.* from OPENDATASOURCE(''SQLOLEDB'',
''Data Source=phmnldb16\eaudit;user id=XXXX;password=XXXX'').AUDIT_FSA_170_001.AUD170.Workflow sdb1) '
FETCH NEXT FROM C INTO #SERVER,#DB
END
CLOSE C
DEALLOCATE C
SET #QUERY=SUBSTRING(#QUERY,0,LEN(#QUERY)-LEN('UNION ALL'))
PRINT #QUERY
EXEC(#QUERY)
END

How do I get a collection of every value in every column of a table?

I have two tables, Values and SpecialValues.
Values has two columns, RecordID and ValueName.
SpecialValues is a table which contains a single row, and thirty columns named SpecialValueName1, SpecialValueName2, SpecialValueName3, etc.
There are obvious database design problems with this system.
That aside, can someone explain to me how to query SpecialValues so that I can get a collection of all the values of every row from the table, and exclude them from a Select from Values?
There's probably some easy way to do this or create a View for it or something, but I think looking at this code might have broken me for the moment...
EDIT: I'd like a query to get all the individual values from every row and column of a given table (in this case the SpecialValues table) so that the query does not need to be updated the next time someone adds another column to the SpecialValues table.
This creates a #SpecialValuesColumns temporary table to store all the column names from SpecialValues.
It then uses a cursor to insert all the values from each of those columns into another temporary table #ProtectedValues.
It then uses a NOT IN query to exclude all of those values from a query to Values.
This code is bad and I feel bad for writing it, but it seems like the least-worst option open to me right now.
DECLARE #SpecialColumnsCount INT;
DECLARE #Counter INT;
DECLARE #CurrentColumnName VARCHAR(255);
DECLARE #ExecSQL VARCHAR(1024);
SET #Counter = 1;
CREATE TABLE #ProtectedValues(RecordID INT IDENTITY(1,1) PRIMARY KEY NOT NULL, Value VARCHAR(255));
DECLARE #SpecialValuesColumns TABLE (RecordID INT IDENTITY(1,1) PRIMARY KEY NOT NULL, ColumnName VARCHAR(255));
INSERT INTO #SpecialValuesColumns (ColumnName)
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'SpecialValues' AND
DATA_TYPE = 'varchar' AND
CHARACTER_MAXIMUM_LENGTH = 255
SELECT #SpecialColumnsCount = COUNT(*) FROM #SpecialValuesColumns
WHILE #Counter <= #SpecialColumnsCount
BEGIN
SELECT #CurrentColumnName = ColumnName FROM #SpecialValuesColumns WHERE RecordID = #Counter;
SET #ExecSQL = 'INSERT INTO #ProtectedValues (Value) SELECT ' + #CurrentColumnName + ' FROM SpecialValues'
EXEC (#ExecSQL)
SET #Counter = #Counter + 1;
END
SELECT * FROM Values WHERE ValueName NOT IN (SELECT ValueName COLLATE DATABASE_DEFAULT FROM #ProtectedValues)
DROP TABLE #ProtectedValues;
I might have misunderstood but doesn't this do it?
SELECT * FROM Values
WHERE ValueName NOT IN (
SELECT SpecialValueName1 FROM SpecialValues
UNION SELECT SpecialValueName2 FROM SpecialValues
UNION SELECT SpecialValueName3 FROM SpecialValues
etc..
)
You could of course make the subquery into a view instead.
*Edit:
This is quite ugly but should solve your problem:
First Create procedure #1
CREATE PROCEDURE [dbo].[SP1]
As
DECLARE
#Query nvarchar(MAX),
#Table nvarchar(255),
#Columns nvarchar(255)
CREATE TABLE #TempTable (Value nvarchar(255))
SET #Table = 'SpecialValues'
SELECT [COLUMN_NAME]
FROM [INFORMATION_SCHEMA].[COLUMNS]
WHERE [TABLE_NAME] = #Table
DECLARE Table_Cursor CURSOR FOR
SELECT COLUMN_NAME
FROM [INFORMATION_SCHEMA].[COLUMNS]
WHERE [TABLE_NAME] = #Table
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO #Columns
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO #TempTable EXEC SP2 #Columns = #Columns, #Table = #Table
FETCH NEXT FROM Table_Cursor INTO #Columns
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor
SELECT ValueName FROM Value WHERE Value NOT IN (SELECT * FROM #TempTable)
TRUNCATE TABLE #TempTable
DROP TABLE #TempTable
Then Create procedure #2
CREATE PROCEDURE [dbo].[SP2]
#Columns nvarchar(255) = '',
#Table nvarchar(255)
AS
DECLARE
#Query nvarchar(MAX)
SET #Query = 'SELECT TOP 1 CONVERT(nvarchar, ' + #Columns + ') FROM ' + #Table
EXEC (#Query)
Then lastly execute the procedure
EXEC SP1
You need to unpivot the values in specialvalues. A pretty easy way to do that is with cross apply syntax:
select sv.value
from specialvalues sv cross apply
(values(sv.SpecialValueName1), (sv.SpecialValueName2), . . .
) sv(value)
where sv.value is not null;
You can exclude these from the list using not in, not exists or a left join.
What ever way you cut it, you have to specify the columns in SpecialValues, you can do this with a long set of UNION queries, or use UNPIVOT:
select SpecialValue
from (select SpecialValueName1,SpecialValueName2,SpecialValueName3 from #SpecialValues) p
unpivot (SpecialValue FOR ROW IN (SpecialValueName1,SpecialValueName2,SpecialValueName3))
AS unpvt
You can then incorporate this into a query on Values using NOT IN
select * from [Values] where ValueName not in (
select SpecialValue
from (select SpecialValueName1,SpecialValueName2,SpecialValueName3 from #SpecialValues) p
unpivot (SpecialValue FOR ROW IN (SpecialValueName1,SpecialValueName2,SpecialValueName3))
AS unpvt
)

Determine all columns from a table and write them separated by commas in a variable

--Dummy table
create table table1 (
column_order varchar (100)
)
insert into table1 values ('column1')
insert into table1 values ('column2')
insert into table1 values ('column3')
insert into table1 values ('column4')
insert into table1 values ('column5')
insert into table1 values ('column6')
--Start of select
declare #rowsCount INT
declare #i INT = 1
declare #column varchar(1000) = ''
set #rowsCount = (select COUNT(*) from table1)
while #i <= #rowsCount
begin
set #column = #column + (select column_order from table1 where rowid(table1) = #i) + ', '
set #i = #i + 1
end
select #column
This code has the function ROWID thats an IQ-Sybase funktion, and im not sure what other DBMS can use it. And above you have a example what i want my select to look like.
My problem is, you cant use the ROWID function with sys.column or any other systables. Has anyone an idea how to get the same select as mine without using the ROWID function.
If you are using IQ, i constructed the code so you can just type f5 and see the select statement, after that just drop the dummy table.
Use list(). It works in both the ASA system and IQ catalogs.
drop table if exists table1
go
create local temporary table table1 (
column_order varchar (100)
) in system --create table in system
insert into table1 values ('column1')
insert into table1 values ('column2')
insert into table1 values ('column3')
insert into table1 values ('column4')
insert into table1 values ('column5')
insert into table1 values ('column6')
declare #columns varchar(100)
select #columns = list(column_order) from table1
select #columns
go
I may be not understand your need, because I can't see why you need rowdid.
Usually, in TSQL, I do as follow:
declare #someVar as nvarchar(max)
set #someVar = (select
'[' + c.name + '],' as 'data()'
from
sys.columns c
join sys.tables t on c.object_id = t.object_id
where
t.name = 'SomeTableName'
for xml path(''))
print Left(#someVar, Len(#someVar) - 1)
Maybe you will need to use a cursor:
-- #MyTableID has to be definded somewhere or replace
DECLARE #columns varchar(32000)
DECLARE my_cursor CURSOR FOR
SELECT syscolumn.column_name FROM syscolumn WHERE syscolumn.table_id = #MyTableID
OPEN my_cursor
FETCH NEXT my_cursor into #column
WHILE ##FETCH_STATUS = 0
BEGIN
-- put your magic here
-- e.g.
-- SET #columns = #columns + column
FETCH NEXT my_cursor_pkey into #column
END
CLOSE my_cursor
DEALLOCATE my_cursor
Not tested yet, but something like that should work.