SQL Server INSERT in Loop - sql

I have this SQL Script:
DECLARE #Loop INT
SET #Loop = 1
DECLARE #Result table([1] int, [2] int,[3] int,[4] int,[5]);
WHILE (#Loop <=5)
BEGIN
INSERT INTO #Result(#Loop)
SELECT Id FROM Students WHERE Id=#Loop
SET #Loop= #Loop+ 1
END
I got an error in this line:
INSERT INTO #Result(#Loop)
Is it possible to use this way to insert data into column names using loop ? I mean dynamicaly
Thanks

This is as close as I can get to what you have.
I'm using dynamic sql to build the insert sql.
I'm using a temporary table #Result instead of a variable #Result because the scope of the #Result variable would mean that this technique would not work.
DECLARE #Loop INT;
SET #Loop = 1;
CREATE TABLE #Result([1] int, [2] int, [3] int, [4] int, [5] int);
DECLARE #Sql AS NVARCHAR(MAX);
DECLARE #LoopNVARCHAR AS NVARCHAR(10);
WHILE (#Loop <= 5)
BEGIN
SET #LoopNVARCHAR = CAST(#Loop AS NVARCHAR(10));
SET #Sql = N'INSERT INTO #Result([' + #LoopNVARCHAR + ']) SELECT Id FROM Students WHERE Id = ' + #LoopNVARCHAR;
exec (#Sql)
SET #Loop = #Loop + 1
END
SELECT * FROM #Result
DROP TABLE #Result

Related

Creating SQL tables dynamically in a loop

I need to dynamically create X tables. The X is calculated on the fly based on a series of other calculations that get passed in. I've written the following dynamic code in an effort to create a loop and generate a create statement each time.
I can't use global tables for this project.
DECLARE #cnt_v varchar(10)
DECLARE #SQL NVARCHAR(max) = ''
DECLARE #season_counter int = 5
SET #cnt = 1
SET #cnt_v = CONVERT(varchar(10), #cnt)
WHILE #cnt <= #season_counter
BEGIN
select #SQL = #SQL + 'create table #Season_year' + #cnt_v + ' (customer_no int, order_no int, order_dt datetime, season_no int)'
exec sp_executesql #SQL
set #sql = ''
select #SQL = #SQL + 'select * from #Season_year' + #cnt_v
exec sp_executesql #SQL
select #cnt = #cnt + 1
select #cnt_v = CONVERT(varchar(10), #cnt)
select #sql = ''
END
The output of the above code is the following errors
When manually create the tables, by typing
create table #Season_year1 (customer_no int, order_no int, order_dt datetime, season_no int)'
then use my dynamic loop to insert data, update records and ultimately drop the temp tables everything works without an issue. The problem is solely creating the tables dynamically.
If this approach isn't going to work, how else could I do this?
Thank you
Each one of your dynamic sql statements is run within its own scope, so in the SELECT * FROM #Season_year5 has no idea what #Season_year5 is. In the first dynamic SQL statement it's created and destroyed all with the execution of sp_executesql. If you combine them both into a single dynamic SQL statement then you will be able to access the temp table in other statements.
DECLARE #cnt INT = 1;
DECLARE #cnt_v varchar(10)
DECLARE #SQL NVARCHAR(max) = ''
DECLARE #season_counter int = 5
SET #cnt = 1
SET #cnt_v = CONVERT(varchar(10), #cnt)
WHILE #cnt <= #season_counter
BEGIN
select #SQL = #SQL + N'create table #Season_year' + #cnt_v + N' (customer_no int, order_no int, order_dt datetime, season_no int);
select * from #Season_year' + #cnt_v + N';'
exec sp_executesql #SQL
select #cnt = #cnt + 1
select #cnt_v = CONVERT(varchar(10), #cnt)
select #sql = ''
END

Insert into a table multiple variables using dynamic query

I'm trying to use an interim dynamic query to insert data into a table variable and then use that table variable to execute a final query. I have an error "must declare scalar variable "
DECLARE #t TABLE ( TableName NVARCHAR(250) )
declare #i as int = 1, #A_1 NVARCHAR(250) ='ABC', #A_2 NVARCHAR(250) ='XYZ', #A_3 NVARCHAR(250) = 'AEI';
WHILE (#i <= 3)
BEGIN
DECLARE #q NVARCHAR(MAX) = ' DECLARE #t TABLE ( TableName NVARCHAR(250) )
insert into #t
select #A_' + CAST(#i AS VARCHAR) + ' as field
from #t
'
INSERT INTO #t
EXEC(#q)
SET #i = #i + 1
END
SELECT * FROM #t
the expected result should be:
TableName
ABC
XYZ
AEI
variable #A_X could have 1 or 15 variables (#A_1, #A_2....#A15)
Instead of table variable you can use temp table. Check this out:
DROP TABLE #TableList
GO
CREATE TABLE #TableList (
A_1 NVARCHAR(250)
,A_2 NVARCHAR(250)
,A_3 NVARCHAR(250)
)
DROP TABLE #Result
GO
CREATE TABLE #Result (
TableName NVARCHAR(250)
)
INSERT INTO #TableList
VALUES('ABC','XYZ','AEI')
DECLARE #q NVARCHAR(MAX)='';
DECLARE #i as int = 1
WHILE (#i <= 3)
BEGIN
SET #q = #q+CHAR(13)+'
INSERT INTO #Result(TableName)
SELECT A_' + CAST(#i AS VARCHAR) + ' from #TableList;'
SET #i = #i + 1
END
EXEC sp_executesql #q
PRINT (#q)
SELECT *
FROM #Result

How to declare temponary/variable table with a dynamic number of column

I have table like this:
Table Name|Number of columns
How to dynamically create temporary tables inside stored procedure with names from first table, and variable columns named e.g. col1, col2, etc..
I also need to insert values to them and make another logic on them.
Example:
Table1|3
Table1(col1 nvarchar(max), col2 nvarchar(max), col3 nvarchar(max))
You will need to use dynamic sql like below:
declare #counter int = 1
declare #numberOfCols int = 3 -- OR you can use ->(select numberofcolumns from firsttable)
declare #dynamic nvarchar(max) = ''
declare #sql nvarchar(max) = 'CREATE TABLE #TEMP (';
while #counter <= #numberofCols
begin
set #dynamic = #dynamic + 'col'+cast(#counter as nvarchar(5))+' nvarchar(max) ';
if(#counter <> #numberOfCols)
begin
set #dynamic = #dynamic + ', ';
end
set #counter = #counter + 1
end
set #sql = #sql + #dynamic + ') select * from #temp'
select #sql
EXECUTE sp_executesql #sql
I have created a stored procedure regarding your question. I wish it can help you.
ALTER PROCEDURE P_ProcedureName
#NumberOfColumns INT=2 --expected 1 or more column
AS
DECLARE #SQLString VARCHAR(MAX)=''
DECLARE #Seq INT=2
IF #NumberOfColumns=0
BEGIN
SELECT 'Please add valid number of column'
RETURN
END
CREATE TABLE #Table
(
Id INT NOT NULL IDENTITY(1,1)
,Column1 VARCHAR(MAX)
)
WHILE #Seq<=#NumberOfColumns
BEGIN
SET #SQLString=#SQLString+'ALTER TABLE #Table ADD Column'+CAST(#Seq AS VARCHAR)+' VARCHAR(MAX)'+char(13)
PRINT(#SQLString)
SET #Seq +=1
END
EXEC(#SQLString)
SELECT * FROM #Table
GO
P_ProcedureName 5

Values not passed to dynamic query in sql server

Is it possible to print the Dynamic select statement after passing the parameters values.When i print the SELECT #SQL.It is giving only select statement without parameter values.In my below procedure the dynamic select statement not giving correct output after passing the parameters.But when i directly passing the the parameter values into the select statement it is giving correct output.In my below procedure splitting function is working fine.Else part in
if statement is not working properly.
CREATE TYPE TableVariable AS TABLE
(
id int identity(1,1),
field_ids INT,
value VARCHAR(MAX)
)
Alter PROCEDURE Testing
(
#TableVar TableVariable READONLY,
#Catalog_id INT
)
AS
Declare #maxPK INT
Declare #pk INT
Declare #fid INT
Declare #is_List SMALLINT
Declare #val VARCHAR(MAX)
Declare #field_Type VARCHAR(50)
Declare #Where VARCHAR(MAX)
Declare #SQL NVARCHAR(MAX);
Set #pk = 1
BEGIN
BEGIN TRY
SET NOCOUNT ON;
Select #maxPK = count(*) From #TableVar
SELECT #Catalog_id
Set #SQL = 'SELECT DISTINCT v1.entity_id from values v1 inner join listings l ON v1.entity_id = l.entity_id WHERE l.c_id=#Catalog_id'
While #pk <= #maxPK
BEGIN
SELECT #fid= field_ids FROM #TableVar where id=#pk;
SELECT #val= value FROM #TableVar where id=#pk;
SELECT #field_Type=type,#is_List=is_list FROM FIELD WHERE ID=#fid
IF (#is_List = 0)
BEGIN
SET #SQL += ' and exists (select 1 from values v'+convert(varchar(15),#pk+1)+' where v1.entity_id = v'+convert(varchar(15),#pk+1)+'.entity_id and v'+convert(varchar(15),#pk+1)+'.field_id=#fid and(value IN(SELECT val FROM spliting(#val,'',''))))'
SELECT #fid
END
else IF (#is_List = 1 OR #field_Type = 'xy')
BEGIN
SET #SQL += ' and exists (select 1 from values v'+convert(varchar(15),#pk+1)+' where v1.entity_id = v'+convert(varchar(15),#pk+1)+'.entity_id and v'+convert(varchar(15),#pk+1)+'.field_id=#fid and(value in(#val)))'
SELECT #fid
END
Select #pk = #pk + 1
END
EXECUTE SP_EXECUTESQL #SQL, N'#Catalog_id int,#fid int,#val varchar(max)',#Catalog_id=#Catalog_id,#fid=#fid,#val=#val
SELECT #SQL
END TRY
BEGIN CATCH
END CATCH
END
DECLARE #DepartmentTVP AS TableVariable;
insert into #DepartmentTVP values(1780,'Smooth As Silk Deep Moisture Shampoo,Smooth As Silk Deeper Moisture Conditioner')
--insert into #DepartmentTVP values(1780,'Smooth As Silk Deeper Moisture Conditioner')
insert into #DepartmentTVP values(1782,'037-05-1129')
insert into #DepartmentTVP values(2320,'["fairtrade","usda_organic","non_gmo_verified"]')
SELECT * FROM #DepartmentTVP
EXEC Testing #DepartmentTVP,583
Yes right before the statment:
EXECUTE SP_EXECUTESQL #SQL, N'#Catalog_id int,#fid int,#val varchar(max)',#Catalog_id=#Catalog_id,#fid=#fid,#val=#val
type:
print #SQL

Pivoting SQL Server 2005 for unknown number of rows

My table is a dynamic one. E.g.:
id SUBJECT
1 his
2 math
3 sci
4 opt
5 ENG
6 SOC
The number of rows is not limited. There could be a hundred. I want output like this:
ID 1 2 3 4 5 6
HIS MATH SCI OPT ENG SOC
I could use a pivot query, but I would have to know the number of columns. How can I do this without knowing the number of columns in advance?
i got an answer but it's very tricky
create a table for all your records
count the records
create a table with that much number of columns
create a comma separated variable for the table which has records
then split the comma separated variables into multiple columns
here is the code
DECLARE #HEADDESC NVARCHAR(150)
DROP TABLE #HEADS
CREATE TABLE #HEADS
(
ID INT IDENTITY
,HEADS NVARCHAR(150)
,NU INT
)
DECLARE #NO INT;
SET #NO = 0
DECLARE C1 CURSOR FOR (
SELECT HEADDESC
FROM GMC.FEEHEAD_MASTER
WHERE CODE = 'GF' AND HEADDESC <> '')
OPEN C1
FETCH NEXT FROM C1 INTO #HEADDESC
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #HEADDESC
SET #NO = #NO+1
INSERT INTO #HEADS(HEADS,NU)
VALUES(#HEADDESC,#NO)
FETCH NEXT FROM C1 INTO #HEADDESC
END
--SELECT * FROM #HEADS
CLOSE C1
DEALLOCATE C1
DECLARE #COLNO INT
SET #COLNO = (SELECT COUNT(*) FROM #HEADS)
DECLARE #COLUMNS VARCHAR(8000)
SELECT #COLUMNS = COALESCE(#COLUMNS +','+ CAST(HEADS AS VARCHAR) ,
CAST(HEADS AS VARCHAR))
FROM #HEADS
--GROUP BY HEADS
DECLARE #value NVARCHAR(100)
SET #value = ',1,STUDENTIDNO,STUDENTNAME,'
SET #COLUMNS = #VALUE+#COLUMNS
SET #COLNO = #COLNO+4
--SELECT #COLUMNS
DROP TABLE #HEADSCOMMA
CREATE TABLE #HEADSCOMMA(HEADS NVARCHAR(3000))
INSERT INTO #HEADSCOMMA VALUES (#COLUMNS)
DROP TABLE #TEMP
CREATE TABLE #TEMP(COL1 NVARCHAR(1000))
DECLARE #SQL NVARCHAR(MAX)
DECLARE #COL NVARCHAR(1000)
DECLARE #COL1 INT
DECLARE #COLNAME NVARCHAR(1000)
SET #COL1 = 2
SET #COL = 'COL'
PRINT #COL1
--SET #COLNAME = #COL +CAST(#COL1 AS NVARCHAR(10))
WHILE #COL1 < =#COLNO
BEGIN
SET #COLNAME = #COL +CAST(#COL1 AS NVARCHAR(100))
PRINT #COLNAME
SET #SQL = 'ALTER TABLE #TEMP ADD '+#COLNAME+' NVARCHAR(100)'
EXEC(#SQL)
SET #COL1= #COL1+1
END
--SELECT * FROM #HEADSCOMMA -- COMMA SEPERATED VALUES
DECLARE #S VARCHAR(8000), #DATA VARCHAR(8000)
--DROP TABLE #NORMALISEDTABLE
--CREATE TABLE #NORMALISEDTABLE (HEADS NVARCHAR(200))
SELECT #S=''
WHILE EXISTS (SELECT * FROM #HEADSCOMMA WHERE HEADS>#S)
BEGIN
SELECT #S=HEADS FROM #HEADSCOMMA WHERE HEADS>#S
PRINT #S
SELECT #DATA=''''+REPLACE(#S,',',''',''')+''''
PRINT #DATA
INSERT INTO #TEMP
EXEC('SELECT '+#DATA)
END
SELECT * FROM #temp
will give the records
Dynamic SQL is an option.