SQL Server 2008 query to convert column values to different columns dynamically - sql-server-2008

I have a table like below:
panelistId DTTM
337322 7/27/2014 19:39
337322 7/27/2014 19:29
317420 7/27/2014 10:22
317420 7/27/2014 10:22
317420 7/27/2014 9:27
336333 7/27/2014 5:41
336333 7/27/2014 3:26
336333 7/27/2014 3:26
336333 7/27/2014 1:25
I am looking for a SQL select query to have below fields from this table:
panelistId | #ofExposures | Exposure_DTTM1 | Exposure_DTTM2 | Exposure_DTTM3 | Exposure_DTTM4 | Exposure_DTTM5 | etc
337322 | 2 | 7/27/2014 19:39 | 7/27/2014 19:29 | | |
Here number of DTTM will be different for each id. If an id will have only 3 DTTM then for rest of the DTTM columns it can be blank.

This should do the trick. Hope it helps
DECLARE #Table2 TABLE (RowID INT IDENTITY(1, 1),
panelistId INT ,
#ofExposures VARCHAR(MAX),
Exposure_DTTMVARCHAR(MAX))
DECLARE #Table TABLE (ID INT ,
DTTM VARCHAR(30)) INSERT INTO #Table (ID,
DTTM) VALUES ('337322', '7/27/2014 19:39'), ('337322', '7/27/2014 19:29'), ('317420', '7/27/2014 10:22'), ('317420', '7/27/2014 10:22'), ('317420', '7/27/2014 9:27'), ('336333', '7/27/2014 5:41'), ('336333', '7/27/2014 3:26'), ('336333', '7/27/2014 3:26'), ('336333', '7/27/2014 1:25'); WITH cte_StageOne
AS (
SELECT ROW_NUMBER() OVER(PARTITION BY id ORDER BY CAST(t.DTTM AS DATETIME) ) AS OrderID, *
FROM #Table AS t
)
INSERT INTO #Table2
SELECT MAX(ID) AS panelistId,
MAX(OrderID) AS #ofExposures,
STUFF((
SELECT ' | ' + cso.DTTM
FROM cte_StageOne AS cso
WHERE ocso.ID = cso.ID
FOR XML PATH('')
), 1, 3, '') AS #Exposure
FROM cte_StageOne AS ocso
GROUP BY ID
--SELECT * FROM #Table2
DECLARE #MaxDTTM INT DECLARE #StartLoop INT DECLARE #EndLoop INT DECLARE #ColumnList VARCHAR(MAX)
SELECT #MaxDTTM = MAX(#ofExposures),
#EndLoop = MAX(RowID),
#StartLoop = MIN(RowID) FROM #Table2
SET #ColumnList = 'panelistId|#ofExposures|Exposure_DTTM1'
WHILE #StartLoop <= #EndLoop
BEGIN
SET #ColumnList = #ColumnList + '|Exposure_DTTM' + CAST(#StartLoop + 1 AS VARCHAR(3))
SET #StartLoop = #StartLoop + 1
END SET #ColumnList = #ColumnList
SET #StartLoop = 1
WHILE #StartLoop <= #EndLoop
BEGIN
DECLARE #in_panelistId VARCHAR(10)
DECLARE #in_ofExposures VARCHAR(10)
DECLARE #in_Exposure_DTTM VARCHAR(MAX)
SELECT #in_panelistId = panelistId,
#in_ofExposures = #ofExposures,
#in_Exposure_DTTM = Exposure_DTTM
FROM #Table2
WHERE RowID = #StartLoop
SET #ColumnList = #ColumnList + CHAR(13) + CHAR(10) + #in_panelistId + '|' + #in_ofExposures + '|' + #in_Exposure_DTTM + REPLICATE('|', #MaxDTTM - #in_ofExposures)
--PRINT REPLICATE('|',#MaxDTTM - #in_ofExposures)
SET #StartLoop = #StartLoop + 1
END PRINT #ColumnList

Related

SQL HTML Email Column Format instead of row format

I'm trying to figure out how to flip this from a table format to a column format.
Hi, I know how to create a SQL HTML Email via table format: i.e
Customer Address City
Joe 123 Here Oakland
but i need to be able to flip this to look like
Customer: Joe
Address: 123 Here
City: Oakland
I'm using SQL 2012
Any help would be appreciated
Please advise
DECLARE #xmlinv NVARCHAR(MAX);
DECLARE #bodyinv NVARCHAR(MAX);
DECLARE #trrowinv NVARCHAR(MAX);
DECLARE #tempemaillistinv NVARCHAR(MAX);
DECLARE #subject_anomaly NVARCHAR(MAX);
SET #subject_anomaly
= N'Inventory Adjustments ' + CAST(#COUNTSinv AS VARCHAR(3)) + N' '
+ LEFT(CONVERT(VARCHAR(10), GETDATE(), 101), 3) + SUBSTRING(CONVERT(VARCHAR(10), GETDATE(), 101), 4, 3)
+ RIGHT(CONVERT(VARCHAR(10), GETDATE(), 101), 2);
SET #xmlinv
= CAST(
(
SELECT T4.product AS 'td',
'',
T4.available AS 'td',
'',
CASE
WHEN T4.quarantine IS NULL THEN
0
ELSE
T4.quarantine
END AS 'td',
'',
CASE
WHEN T4.labels IS NULL THEN
0
ELSE
T4.labels
END AS 'td',
'',
T4.MinLog AS 'td',
'',
T.available AS 'td',
'',
CASE
WHEN T.quarantine IS NULL THEN
0
ELSE
T.quarantine
END AS 'td',
'',
CASE
WHEN T.labels IS NULL THEN
0
ELSE
T.labels
END AS 'td',
'',
T.MinLog AS 'td'
--SELECT T4.product,T4.available,T4.quarantine,T4.labels,T4.MinLog,T.available,T.quarantine,T.labels,T.MinLog
FROM #t4 AS T4
LEFT OUTER JOIN #t3 AS T3
ON T4.MaxRow2 = T3.MaxRow
AND T4.product = T3.product
LEFT OUTER JOIN #t2 AS T2
ON T4.MaxRow2 = T2.MaxRow
AND T4.product = T2.product
LEFT OUTER JOIN #temp AS T
ON T4.MaxRow2 = T.therow + 1
AND T4.product = T.product
ORDER BY 1
--ORDER BY 1,3 desc
FOR XML PATH('tr'), ELEMENTS
)
AS
NVARCHAR(MAX));
SET #bodyinv
= N'<html><H2>Adjustments</H2><body bgcolor=white><table border=1 style=''border:1px;background-color:#FFFFCC;bordercolor:#FFCC00'' cellpadding=''1'' cellspacing=''0''>';
SET #trrowinv
= N'<tr><th>Product</th><th>NewAvailable</th><th>NewQuarantine</th><th>NewLabels</th><th>LastUpdate</th><th>OldAvailable</th><th>OldQuarantine</th><th>OldLabels</th><th>PriorUpdate</th></tr>';
SET #bodyinv = #bodyinv + #trrowinv + #xmlinv + N'</table></body></html>';
SET #tempemaillistinv = N'abc#abc.com';
EXEC [msdb].[dbo].[sp_send_dbmail] #recipients = #tempemaillistinv,
#body = #bodyinv,
#body_format = 'HTML',
#subject = #subject_anomaly,
#profile_name = 'abc';

Stored Procedure is taking more time to execute

I am executing a stored procedure im MYSQL. That will generate 6000 records and insert that 6000 records into a Table. For this, that stored procedure is taking more than 45 min.The file size of stored procedure is 45kb. Systems RAM is 0.98GB.
Does system RAM affecting the stored procedure performance?
CREATE DEFINER=`root`#`localhost` PROCEDURE `sample`()
BEGIN
Declare FY_LHS Varchar(20);
Declare FY_RHS Varchar(20);
Declare abc int default 0;
Declare bcd varchar(40) default null;
Declare cde int default 0;
Declare def varchar(40) default null;
Declare efg int default 0;
Declare ghi varchar(40) default null;
Declare ijk varchar(40) default null;
Declare hij varchar(40) default null;
Declare ijk varchar(40) default null;
Declare param_month int ;
Declare monthsortsequence int default 0;
Declare p int default 0;
Declare q int default 0;
Declare r int default 0;
Declare s int default 0;
Declare t int default 0;
DECLARE done INT DEFAULT FALSE;
declare dateofdisch int default 0;
Declare fId int default 0;
DECLARE fac_cur CURSOR FOR SELECT r FROM u ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET param_month = Month(CURDATE());
IF param_month = 4 THEN SET monthsortsequence = 1;
ELSEIF param_month = 5 THEN SET monthsortsequence = 2;
ELSEIF param_month = 6 THEN SET monthsortsequence = 3;
ELSEIF param_month = 7 THEN SET monthsortsequence = 4;
ELSEIF param_month = 8 THEN SET monthsortsequence = 5;
ELSEIF param_month = 9 THEN SET monthsortsequence = 6;
ELSEIF param_month = 10 THEN SET monthsortsequence = 7;
ELSEIF param_month = 11 THEN SET monthsortsequence = 8;
ELSEIF param_month = 12 THEN SET monthsortsequence = 9;
ELSEIF param_month = 1 THEN SET monthsortsequence = 10;
ELSEIF param_month = 2 THEN SET monthsortsequence = 11;
ELSEIF param_month = 3 THEN SET monthsortsequence = 12;
END IF;
OPEN fac_cur;
read_loop: LOOP
FETCH fac_cur INTO fId;
IF fId >= 65 THEN
LEAVE read_loop;
END IF;
IF fId != 0 THEN
IF MONTH(CURDATE())>=4 THEN
Set FY_LHS = YEAR(CURDATE());
Set FY_RHS = YEAR(CURDATE())+1;
ELSE
Set FY_LHS = YEAR(CURDATE())-1;
Set FY_RHS = YEAR(CURDATE());
END IF;
Select tblbc.StateId, tblst.StateName, tblbc.DistrictId,
tblst.District, tblbc.kID, tblst.k, tblbc.FacilityName, tblbc.FacilityType,
tblbc.ReportingToId
into abc, bcd, cde, def, efg, ghi, ijk, hij, ijk
from u tblbc inner join tblstateinfo tblst on
tblbc.stateid = tblst.stateid and tblbc.DistrictId = tblst.dcode and tblbc.kID = tblst.tcode
where tblbc.r = fId;
Delete from data where Year = concat(FY_LHS,'-',FY_RHS) and Month = param_month and r = fId;
Set p = (select count(*) as Count from w tblreg inner join tblp1s tblu on tblreg.p1id = tblu.p1id where tblreg.pm = 0 and (Str_To_Date(tblreg.ty, '%d/%m/%Y') between Str_To_Date(concat(FY_LHS,'/04/01'), '%Y/%m/%d') and Str_To_Date(concat(FY_RHS,'/03/31'), '%Y/%m/%d')) and month(Str_To_Date(tblreg.ty, '%d/%m/%Y')) = param_month and tblu.r = fId);
Set q = (Select count(ytid) as Count From w reg inner join tblp1s tblu on reg.p1id = tblu.p1Id where datediff(CurDate(), Str_To_Date(reg.LMP, '%d/%m/%Y')) < 300 and reg.pm = 0 and (Str_To_Date(reg.ty, '%d/%m/%Y') between Str_To_Date(concat(FY_LHS,'/04/01'), '%Y/%m/%d') and Str_To_Date(concat(FY_RHS,'/03/31'), '%Y/%m/%d')) and month(Str_To_Date(reg.ty, '%d/%m/%Y')) = param_month and tblu.r = fId);
Set r = (Select count(reg.ytid) from (Select ts.p1id, ts.ytid, count(ts.ytid) as count from tblhjlist ts where ts.fgtype = 'ANC' and ts.actualdateofaction is not null and (Str_To_Date(actualdateofaction, '%d/%m/%Y') between Str_To_Date(concat(FY_LHS,'/04/01'), '%Y/%m/%d') and Str_To_Date(concat(FY_RHS,'/03/31'), '%Y/%m/%d')) and month(Str_To_Date(actualdateofaction, '%d/%m/%Y')) = param_month group by ts.ytid, ts.p1id) tss left join w reg on tss.ytid = reg.ytid inner join tblp1s tblu on reg.p1Id = tblu.p1id where tss.count = 3 and tblu.r = fId);
Set s = (Select count(sl.ytid) from (Select p1id, ytid from tblhjlist where fgid = 1 and fgtype = 'FT' and actualdateofaction is not null and (Str_To_Date(actualdateofaction, '%d/%m/%Y') between Str_To_Date(concat(FY_LHS,'/04/01'), '%Y/%m/%d') and Str_To_Date(concat(FY_RHS,'/03/31'), '%Y/%m/%d')) and month(Str_To_Date(actualdateofaction, '%d/%m/%Y')) = param_month) sl inner join w reg on sl.ytid = reg.ytid inner join tblp1s tblu on reg.p1id = tblu.p1id and reg.pm = 0 and tblu.r = fId);
Set t = (Select count(ts.ytid) from (Select p1id, ytid from tblhjlist where ((fgtype = 'FT' and fgid = 2) or (fgtype = 'FTBooster' and fgid = 3)) and actualdateofaction is not null and (Str_To_Date(actualdateofaction, '%d/%m/%Y') between Str_To_Date(concat(FY_LHS,'/04/01'), '%Y/%m/%d') and Str_To_Date(concat(FY_RHS,'/03/31'), '%Y/%m/%d')) and month(Str_To_Date(actualdateofaction, '%d/%m/%Y')) = 9 group by ytid) ts inner join w reg on ts.ytid = reg.ytid inner join tblp1s tblu on reg.p1Id = tblu.p1Id and reg.pm = 0 and tblu.r = fId);
.
.
.
.
.
40 queries
insert into data (year, month, stateId, state, districtId, district, kid, k, facilityname, facilityType, sortsequenceMonth, r, sortsequence, itemRefno, itemvalue, ReportingToId) values (concat(FY_LHS,'-',FY_RHS), param_month, abc, bcd, cde, def, efg, ghi, ijk, hij, monthsortsequence, fId, 2, '1.1.1', q, ijk);
insert into data (year, month, stateId, state, districtId, district, kid, k, facilityname, facilityType, sortsequenceMonth, r, sortsequence, itemRefno, itemvalue, ReportingToId) values (concat(FY_LHS,'-',FY_RHS), param_month, abc, bcd, cde, def, efg, ghi, ijk, hij, monthsortsequence, fId, 1, '1.1', p, ijk);
insert into data (year, month, stateId, state, districtId, district, kid, k, facilityname, facilityType, sortsequenceMonth, r, sortsequence, itemRefno, itemvalue, ReportingToId) values (concat(FY_LHS,'-',FY_RHS), param_month, abc, bcd, cde, def, efg, ghi, ijk, hij, monthsortsequence, fId, 3, '1.3', r, ijk);
insert into data (year, month, stateId, state, districtId, district, kid, k, facilityname, facilityType, sortsequenceMonth, r, sortsequence, itemRefno, itemvalue, ReportingToId) values (concat(FY_LHS,'-',FY_RHS), param_month, abc, bcd, cde, def, efg, ghi, ijk, hij, monthsortsequence, fId, 4, '1.4.1', s, ijk);
insert into data (year, month, stateId, state, districtId, district, kid, k, facilityname, facilityType, sortsequenceMonth, r, sortsequence, itemRefno, itemvalue, ReportingToId) values (concat(FY_LHS,'-',FY_RHS), param_month, abc, bcd, cde, def, efg, ghi, ijk, hij, monthsortsequence, fId, 5, '1.4.2', t, ijk);
.
.
.
.
40 insert statements
set fId = fId + 1;
END IF;
END LOOP;
CLOSE fac_cur;
END
You need to check which statement exactly in the stored procedure
is taking time by adding some debug points (ex: You can insert
timestamp after each select into some temp table).
You need to check that you have proper indexes on table for select
queries.

Counting distinct multi-column patterns

I'm using SQL Server 2014 and i nee some help with a hard query.
I have the following table (MyTable). These columns names are just for the example. They are actually totally different from each other.
id int,
col1 int,
col2 int,
..
..
..
col70 int
For each pairs of sequential columns {(col1, col2), (col2_col3)...(col69_col70)}, i need to calculate the following: The number of different pairs that each values has - col_i is the static column, and col_i+1 is the other one. Each value need to be divided by the total amount of records in the table. For example:
col1 | col2
45 | 789
56 | 345
99 | 234
45 | 789
45 | 222
89 | 678
89 | 345
45 | 789
90 | 234
12 | 567
Calculation:
((45, 789)+(45, 222))/10
(56, 345)/10
(99, 234)/10
(45, 789)+(45, 222)/10
(45, 789)+(45, 222)/10
(89, 678)+(89, 345)/10
(89, 678)+(89, 345)/10
((45, 789)+(45, 222))/10
(90, 234)/10
(12, 567)/10
Output:
col1_col2
0.2
0.1
0.1
0.2
0.2
0.2
0.2
0.2
0.1
0.1
Explanation for the first records:
45 is the value of the static column ,so now i'll check how many different combination we can find with col2:
45 | 789
45 | 789
45 | 222
45 | 789
Total distinct combinations divided by number of records in the table: 2/10 = 0.2
This calculation need for each pairs of sequential columns. Any recommendation? Is there's a smart way to calculate it automatically instead of writing a query with line for each pair?
An example assuming you have a primary key:
create table my_table
(column_id int not null,
column1 int not null,
column2 int not null);
insert into my_table
(column_id, column1, column2)
values
(1, 45,789),
(2, 56,345),
(3, 99,234),
(4, 45,789),
(5, 45,222),
(6, 89,678),
(7, 89,345),
(8, 45,789),
(9, 90,234),
(10, 12,567);
declare #column_a as nvarchar(100) = N'column1';
declare #column_b as nvarchar(100) = N'column2';
declare #result_column as nvarchar(100) = N'column1_2';
declare #sql_string as nvarchar(4000)
set #sql_string =
'select a.column_id,
1.0 * count( distinct b.' + #column_b + ') / (count(a.' + #column_a + ') over ()) as ' + #result_column
+ ' from my_table a
inner join my_table b
on a.' + #column_a + ' = b.' + #column_a +
' group by a.column_id, a.' + #column_a +
' order by a.column_id';
-- print #sql_string;
execute(#sql_string);
If there's no primary key you could use the rownumber() function to create an identifier, but the result order would change. The print command can be useful for checking the dynamic sql string, here commented out.
Putting the dynamic SQL into a stored procedure:
create procedure column_freq #column_a nvarchar(100), #column_b nvarchar(100), #result_column nvarchar(100)
as
begin
declare #sql_string as nvarchar(4000);
set #sql_string =
'select a.column_id,
1.0 * count( distinct b.' + #column_b + ') / (count(a.' + #column_a + ') over ()) as ' + #result_column
+ ' from my_table a
inner join my_table b
on a.' + #column_a + ' = b.' + #column_a +
' group by a.column_id, a.' + #column_a +
' order by a.column_id';
execute(#sql_string);
end;
go
exec column_freq N'column1', N'column2', N'column1_2';
go

SQL dynamically pivot and group results

I have a table set up like below:
CLIENTNAME MONTHANDYEAR RESOURCE COST
abc JAN2011 res1 1000
abc FEB2011 res1 2000
def JAN2011 res2 1500
def MAR2011 res1 2000
ghi MAR2011 res3 2500
I need an output like below. Months are to be generated dynamically in 3-month intervals. In this case, is there a way to pivot by MONTHANDYEAR as well as group by clientname?
RESOURCE CLIENTNAME JAN2011 FEB2011 MAR2011
res1 abc 1000 1000
res1 def 2000
res2 def 1500
res3 ghi 2500
This is what the PIVOT operator is for:
SELECT
Resource, ClientName,
[JAN2011], [FEB2011], [MAR2011]
FROM
(
SELECT
*
FROM tblname
) AS SourceTable
PIVOT
(
SUM(COST)
FOR MONTHANDYEAR IN ([JAN2011], [FEB2011], [MAR2011])
) AS PivotTable;
Since your months are selected dynamically using #startDate as a base month, you can use the following dynamic query:
DECLARE #startDate datetime
SET #startDate = '2011-01-01'
DECLARE #sql varchar(MAX)
SET #sql = 'SELECT
Resource, ClientName, [' +
REPLACE(SUBSTRING(CONVERT(varchar, #startDate, 13), 4, 8), ' ', '') + '], [' +
REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 1, #startDate), 13), 4, 8), ' ', '') + '], [' +
REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 2, #startDate), 13), 4, 8), ' ', '') + ']
FROM
(
SELECT
*
FROM tblName
) AS SourceTable
PIVOT
(
SUM(COST)
FOR MONTHANDYEAR IN (' +
QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, #startDate, 13), 4, 8), ' ', '')) + ', ' +
QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 1, #startDate), 13), 4, 8), ' ', '')) + ', ' +
QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 2, #startDate), 13), 4, 8), ' ', '')) + ')
) AS PivotTable'
execute(#sql)
working sqlfiddle here
This data transformation can be done with the PIVOT function.
If you know the values, then you can hard-code the monthandyear dates:
select resource,
clientname,
isnull(jan2011, '') Jan2011,
isnull(feb2011, '') Feb2011,
isnull(mar2011, '') Mar2011
from
(
select clientname, monthandyear, resource, cost
from yourtable
) src
pivot
(
sum(cost)
for monthandyear in (Jan2011, Feb2011, Mar2011)
) piv;
See SQL Fiddle with Demo.
But if the dates are unknown, then you will need to use dynamic SQL:
DECLARE #cols AS NVARCHAR(MAX),
#colNames AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(monthandyear)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select #colNames = STUFF((SELECT distinct ', isnull(' + QUOTENAME(monthandyear)+', 0) as '+QUOTENAME(monthandyear)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT resource, clientname,' + #colNames + ' from
(
select clientname, monthandyear, resource, cost
from yourtable
) x
pivot
(
sum(cost)
for monthandyear in (' + #cols + ')
) p '
execute(#query)
See SQL Fiddle with Demo.
The result of both is:
| RESOURCE | CLIENTNAME | JAN2011 | FEB2011 | MAR2011 |
-------------------------------------------------------
| res1 | abc | 1000 | 2000 | 0 |
| res1 | def | 0 | 0 | 2000 |
| res2 | def | 1500 | 0 | 0 |
| res3 | ghi | 0 | 0 | 2500 |
SELECT Resource, Clientname
, SUM(CASE WHEN MonthAndYear = 'JAN2011' THEN COST ELSE 0 END) AS JAN2011
, SUM(CASE WHEN MonthAndYear = 'FEB2011' THEN COST ELSE 0 END) AS FEB2011
, SUM(CASE WHEN MonthAndYear = 'MAR2011' THEN COST ELSE 0 END) AS MAR2011
FROM yourtable
GROUP BY Resource, Clientname
You can also remove the ELSE 0 to return a NULL value for resource/clientname combinations without data

Create test table in SQL Server 2008

How can I create a table with x attributes and n rows like?
For example:
x = 4 , and n = 10
att1 att2 att3 att4
----------------------
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
declare #x int = 4, #n int = 10
declare #strg nvarchar(1000) = 'create table myTable ('
declare #i int = 1
while #i<= #x
begin
set #strg = #strg + 'att' + cast(#i as varchar(5))+ ' int default ' + CAST(#i as varchar(5)) + ','
set #i = #i + 1
end
set #strg = SUBSTRING(#strg, 1, LEN(#strg)-1) + ')'
-- this creates your table
exec sp_executesql #strg
-- now lets insert rows
set #i = 0
while #i < #n
begin
INSERT INTO myTable DEFAULT VALUES;
set #i = #i + 1
end
-- lets check
select *
from myTable
Here's a script. You could put this into a stored procedure or just leave it as it is. All you have to do is update the initial col and row values.
DECLARE
#cols INT = 4,
#rows INT = 10,
#tablename VARCHAR(20) = 'TestTable'
DECLARE
#i INT = 1,
#j INT = 1,
#sql NVARCHAR(MAX) = 'create table ' + #tablename + '('
WHILE(#i <= #cols)
BEGIN
SET #sql = #sql + 'att' + CAST(#i AS VARCHAR(10)) + ' VARCHAR(10)'
IF NOT #i = #cols
BEGIN
SET #sql = #sql + ', '
END
SET #i = #i + 1
END
SET #sql = #sql + ')'
EXECUTE sp_executesql #sql
SET #sql = 'INSERT INTO ' + #tablename + ' VALUES'
WHILE(#j <= #rows)
BEGIN
SET #i = 1
SET #sql = #sql + '('
WHILE(#i <= #cols)
BEGIN
SET #sql = #sql + '''' + CAST(#i AS VARCHAR(10)) + ''''
IF NOT #i = #cols
BEGIN
SET #sql = #sql + ', '
END
SET #i = #i + 1
END
IF NOT #j = #rows
BEGIN
SET #sql = #sql + '), '
END
SET #j = #j + 1
END
SET #sql = #sql + ')'
EXECUTE sp_executesql #sql
Hope this helps.