I'm trying to get different values from my While loop I seem to be getting the same value printed 3 times - tsql

I've tried to use a While Loop and I seem to be getting the same value printed 3 times I need to have different values printed.
DECLARE #Counter INT
SET #Counter = 1
WHILE ( #Counter <= (SELECT COUNT(*) FROM #TempTable_Log))
--To handle gaps in the looping column value
BEGIN PRINT #Counter
SELECT #LogbackupFile = physical_device_name, #LogBackupSQL = #LogbackupFile
FROM #TempTable_log
WHERE backup_finish_date > ISNULL(#DiffDate, #FullBackupDate)
AND backup_finish_date > #FullBackupDate
AND backup_finish_date <= #RestoreDate
SET #Counter = #Counter + 1
SET #LogBackupSQL = 'RESTORE LOG ' + #DatabaseNameCopy + ' FROM DISK
= ''' + #LogbackupFile + ''' WITH FILE = 1, NOUNLOAD, STATS = 5,'
PRINT #LogBackupSQL end END
Result
(3 rows affected)
1
RESTORE LOG ns_lots_of_vlfs_copy FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.KUSHALRATTU\MSSQL\Backup\ns_lots_of_vlfs_tran_03_10022023.trn' WITH FILE = 1, NOUNLOAD, STATS = 5,
2
RESTORE LOG ns_lots_of_vlfs_copy FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.KUSHALRATTU\MSSQL\Backup\ns_lots_of_vlfs_tran_03_10022023.trn' WITH FILE = 1, NOUNLOAD, STATS = 5,
3
RESTORE LOG ns_lots_of_vlfs_copy FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.KUSHALRATTU\MSSQL\Backup\ns_lots_of_vlfs_tran_03_10022023.trn' WITH FILE = 1, NOUNLOAD, STATS = 5,
Expected Result
C:\Program Files\Microsoft SQL Server\MSSQL15.KUSHALRATTU\MSSQL\Backup\ns_lots_of_vlfs_tran_03_10022023.trn
C:\Program Files\Microsoft SQL Server\MSSQL15.KUSHALRATTU\MSSQL\Backup\ns_lots_of_vlfs_tran_02_10022023.trn
C:\Program Files\Microsoft SQL Server\MSSQL15.KUSHALRATTU\MSSQL\Backup\ns_lots_of_vlfs_tran_01_10022023.trn

Firstly, the reason for the behaviour is because each iteration of your loop you are doing the same thing. In your SQL you are assigning an arbitrary value to you variable #LogbackupFile and as this value is from a temporary table it has a high likelihood that that arbitrary value will be the same value every time.
Effectively you are doing something like this:
CREATE TABLE #Temp (I int)
INSERT INTO #Temp (I)
VALUES(1),(3),(2); --Intentionally in an "odd" order
GO
DECLARE #C int = 1;
DECLARE #I int;
WHILE #C <= (SELECT COUNT(*) FROM #Temp) BEGIN
--Assign an arbitrary value to #i
SELECT #I = I
FROM #Temp;
PRINT #I;
SET #C = #C + 1;
END;
GO
DROP TABLE #Temp;
This, very likely, returns the value 2 3 times.
In truth, I'm not sure why you want to PRINT these values. Why not just SELECT the dataset you need? This will return multiple rows with a separate RESTORE LOG on each line:
SELECT 'RESTORE LOG ' + #DatabaseNameCopy + ' FROM DISK = ''' + physical_device_name + ''' WITH FILE = 1, NOUNLOAD, STATS = 5,'
FROM #TempTable_log
WHERE backup_finish_date > ISNULL(#DiffDate, #FullBackupDate)
AND backup_finish_date > #FullBackupDate
AND backup_finish_date <= #RestoreDate
ORDER BY backup_finish_date;
If you must PRINT it, you could use string aggregation, assuming that the total value will be less than 8,000 bytes:
DECLARE #Restore nvarchar(4000),
#CRLF nchar(2) = NCHAR(13) + NCHAR(10);
SELECT #Restore = STRING_AGG('RESTORE LOG ' + #DatabaseNameCopy + ' FROM DISK = ''' + physical_device_name + ''' WITH FILE = 1, NOUNLOAD, STATS = 5,',#CRLF) WITHIN GROUP (ORDER BY backup_finish_date)
FROM #TempTable_log
WHERE backup_finish_date > ISNULL(#DiffDate, #FullBackupDate)
AND backup_finish_date > #FullBackupDate
AND backup_finish_date <= #RestoreDate;
PRINT #Restore;
If you must use a WHILE lop (which I suggest against), you need to ensure that you assign a different value each iteration. As I can't see your data, and thus don't know what it in the table, one method would be to DELETE the "first" row each iteration, so that you get a different row each time. This assumes that backup_finish_date and physical_device_name are npth unique values.
DECLARE #Counter int;
SET #Counter = 1;
WHILE (#Counter <= (SELECT COUNT(*)FROM #TempTable_Log))
BEGIN
PRINT #Counter;
SELECT TOP (1)
#LogbackupFile = physical_device_name,
#LogBackupSQL = #LogbackupFile
FROM #TempTable_log
WHERE backup_finish_date > ISNULL(#DiffDate, #FullBackupDate)
AND backup_finish_date > #FullBackupDate
AND backup_finish_date <= #RestoreDate
ORDER BY backup_finish_date;
SET #Counter = #Counter; --I assume this should start at 1, not 2?
SET #LogBackupSQL = 'RESTORE LOG ' + #DatabaseNameCopy + ' FROM DISK = ''' + #LogbackupFile + ''' WITH FILE = 1, NOUNLOAD, STATS = 5,';
PRINT #LogBackupSQL;
DELETE FROM #TempTable_log
WHERE physical_device_name = #LogbackupFile;
END;

Related

Getting Error With GROUP BY when Converting Query to Dynamic SQL

I'm trying to convert the following query to dynamic SQL to allow for variations:
UPDATE T
SET SumCount = J.SUM
FROM #temp T
JOIN (SELECT Count_99221 + COUNT_99222 + Count_99223 [SUM], t2.userID
FROM #temp t2
GROUP BY t2.userID, Count_99221 + COUNT_99222 + Count_99223
) J ON T.userID = J.UserID
This is what I have for the Dynamic SQL:
DECLARE #sql3 nvarchar(2000) =
'UPDATE T ' +
'SET SumCount = J.SumOfColumns ' +
'FROM #temp T ' +
'JOIN (SELECT ' + #columnSumString + ' [SumOfColumns], t2.userID ' +
'FROM #temp t2 ' +
'GROUP BY t2.userID, ' + #columnSumString +
' ) J ON T.userID = J.UserID'
EXEC sp_executesql #sql3
I am receiving the following error only when I run the query as Dynamic SQL:
Each GROUP BY expression must contain at least one column that is not
an outer reference.
Can somebody help explain why this is happening? I am new to Dynamic SQL so I'm not privy to any limitations for running queries this way.
Thank you in advance.
EDIT:
The variable #columnString is a string made by concatenating several other column names, created in the following way:
DECLARE #Cursor Cursor
DECLARE #code varchar(20)
DECLARE #ID INT
SET #cptCursor = CURSOR FOR
SELECT * FROM dbo.Split(#UserInput,CHAR(44))
OPEN #cptCursor
FETCH NEXT FROM #cptCursor INTO #ID, #code
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #colName varchar(50) = 'Count_' + cast(#code as varchar(10))
DECLARE #sql nvarchar(50) = 'ALTER TABLE #temp ADD ' + #colName + ' int'
EXEC sp_executesql #sql
--Code that adds values to each column that is created.....
SET #columnSumString = #colName + ' + ' + #columnSumString
--SET #columnSumString = #code + ' + ' + #columnSumString
FETCH NEXT FROM #cptCursor INTO #ID, #code
END
CLOSE #Cursor
DEALLOCATE #Cursor
SET #columnSumString = SUBSTRING(#columnSumString,1,LEN(#columnSumString)-2)
SELECT #columnSumString
The user input is a comma separated string. "Count_99221 + COUNT_99222 + Count_99223" is just one example of columns created from the user input "99221, 99222, 99223".
I also realized I was concatenating the #code variable into #columnSumString instead of #colName. Now when I run the query I don't get the error (even though I don't understand how the above error message relates to that mistake) but every value of SumCount is NULL.
IMHO you must re-write your query as follow:
UPDATE #temp
SET SumCount =
(SELECT Count_99221 + COUNT_99222 + Count_99223
FROM #temp t2
WHERE t2.userID = #temp.userID)
So the dynamic SQL will become:
DECLARE #columnString varchar(200)
SET #columnString = Count_99221 + COUNT_99222 + Count_99223
DECLARE #sql3 nvarchar(2000) =
N'UPDATE #temp ' +
'SET SumCount = (SELECT ' + #columnString +
' FROM #temp t2 WHERE t2.userID = #temp.userID)'
EXEC sp_executesql #sql3

Arithmetic overflow for smallint where no smallint is present

DECLARE #SchemaName VARCHAR(100)
DECLARE #TableName VARCHAR(256)
DECLARE #IndexName VARCHAR(256)
DECLARE #ColumnName VARCHAR(100)
DECLARE #is_unique VARCHAR(100)
DECLARE #IndexTypeDesc VARCHAR(100)
DECLARE #FileGroupName VARCHAR(100)
DECLARE #is_disabled VARCHAR(100)
DECLARE #IndexOptions VARCHAR(MAX)
DECLARE #IndexColumnId INT
DECLARE #IsDescendingKey INT
DECLARE #IsIncludedColumn INT
DECLARE #TSQLScripCreationIndex VARCHAR(MAX)
DECLARE #TSQLScripDisableIndex VARCHAR(MAX)
DECLARE CursorIndex CURSOR
FOR
SELECT SCHEMA_NAME(t.schema_id) [schema_name] ,
t.name ,
ix.name ,
CASE WHEN ix.is_unique = 1 THEN 'UNIQUE '
ELSE ''
END ,
ix.type_desc ,
CASE WHEN ix.is_padded = 1 THEN 'PAD_INDEX = ON, '
ELSE 'PAD_INDEX = OFF, '
END
+ CASE WHEN ix.allow_page_locks = 1 THEN 'ALLOW_PAGE_LOCKS = ON, '
ELSE 'ALLOW_PAGE_LOCKS = OFF, '
END
+ CASE WHEN ix.allow_row_locks = 1 THEN 'ALLOW_ROW_LOCKS = ON, '
ELSE 'ALLOW_ROW_LOCKS = OFF, '
END
+ CASE WHEN INDEXPROPERTY(t.object_id, ix.name, 'IsStatistics') = 1
THEN 'STATISTICS_NORECOMPUTE = ON, '
ELSE 'STATISTICS_NORECOMPUTE = OFF, '
END
+ CASE WHEN ix.ignore_dup_key = 1 THEN 'IGNORE_DUP_KEY = ON, '
ELSE 'IGNORE_DUP_KEY = OFF, '
END + 'SORT_IN_TEMPDB = OFF,DROP_EXISTING = ON' AS IndexOptions ,
ix.is_disabled ,
FILEGROUP_NAME(ix.data_space_id) FileGroupName
FROM sys.tables t
INNER JOIN sys.indexes ix ON t.object_id = ix.object_id
WHERE ix.type > 0
AND ix.is_primary_key = 0
AND ix.is_unique_constraint = 0 --and schema_name(tb.schema_id)= #SchemaName and tb.name=#TableName
AND t.is_ms_shipped = 0
AND t.name <> 'sysdiagrams'
AND t.name = 'LegalEntity'
ORDER BY SCHEMA_NAME(t.schema_id) ,
t.name ,
ix.name
OPEN CursorIndex
FETCH NEXT FROM CursorIndex INTO #SchemaName, #TableName, #IndexName,
#is_unique, #IndexTypeDesc, #IndexOptions, #is_disabled, #FileGroupName
WHILE ( ##fetch_status = 0 )
BEGIN
DECLARE #IndexColumns VARCHAR(MAX)
DECLARE #IncludedColumns VARCHAR(MAX)
SET #IndexColumns = ''
SET #IncludedColumns = ''
DECLARE CursorIndexColumn CURSOR
FOR
SELECT col.name ,
ixc.is_descending_key ,
ixc.is_included_column
FROM sys.tables tb
INNER JOIN sys.indexes ix ON tb.object_id = ix.object_id
INNER JOIN sys.index_columns ixc ON ix.object_id = ixc.object_id
AND ix.index_id = ixc.index_id
INNER JOIN sys.columns col ON ixc.object_id = col.object_id
AND ixc.column_id = col.column_id
WHERE ix.type > 0
AND ( ix.is_primary_key = 0
OR ix.is_unique_constraint = 0
)
AND SCHEMA_NAME(tb.schema_id) = #SchemaName
AND tb.name = #TableName
AND ix.name = #IndexName
ORDER BY ixc.index_column_id
OPEN CursorIndexColumn
FETCH NEXT FROM CursorIndexColumn INTO #ColumnName, #IsDescendingKey,
#IsIncludedColumn
WHILE ( ##fetch_status = 0 )
BEGIN
IF #IsIncludedColumn = 0
SET #IndexColumns = #IndexColumns + #ColumnName
+ CASE WHEN #IsDescendingKey = 1 THEN ' DESC, '
ELSE ' ASC, '
END
ELSE
SET #IncludedColumns = #IncludedColumns + #ColumnName
+ ', '
FETCH NEXT FROM CursorIndexColumn INTO #ColumnName,
#IsDescendingKey, #IsIncludedColumn
END
CLOSE CursorIndexColumn
DEALLOCATE CursorIndexColumn
SET #IndexColumns = SUBSTRING(#IndexColumns, 1, LEN(#IndexColumns) - 1)
SET #IncludedColumns = CASE WHEN LEN(#IncludedColumns) > 0
THEN SUBSTRING(#IncludedColumns, 1,
LEN(#IncludedColumns) - 1)
ELSE ''
END
-- print #IndexColumns
-- print #IncludedColumns
SET #TSQLScripCreationIndex = ''
SET #TSQLScripDisableIndex = ''
SET #TSQLScripCreationIndex = 'CREATE ' + #is_unique + #IndexTypeDesc
+ ' INDEX ' + QUOTENAME(#IndexName) + ' ON '
+ QUOTENAME(#SchemaName) + '.' + QUOTENAME(#TableName) + '('
+ #IndexColumns + ') '
+ CASE WHEN LEN(#IncludedColumns) > 0
THEN CHAR(13) + 'INCLUDE (' + #IncludedColumns + ')'
ELSE ''
END + CHAR(13) + 'WITH (' + #IndexOptions + ') ON '
+ '[SC_LE]([Id])' + ';'
IF #is_disabled = 1
SET #TSQLScripDisableIndex = CHAR(13) + 'ALTER INDEX '
+ QUOTENAME(#IndexName) + ' ON ' + QUOTENAME(#SchemaName)
+ '.' + QUOTENAME(#TableName) + ' DISABLE;' + CHAR(13)
--print #TSQLScripCreationIndex
--print #TSQLScripDisableIndex
FETCH NEXT FROM CursorIndex INTO #SchemaName, #TableName, #IndexName,
#is_unique, #IndexTypeDesc, #IndexOptions, #is_disabled,
#FileGroupName
END
CLOSE CursorIndex
DEALLOCATE CursorIndex
The issue here is probably where you call FILEGROUP_NAME() in the SELECT clause of the definition of CursorIndex. As per the MSDN definition, the filegroup_id parameter passed to FILEGROUP_NAME() is of type smallint. I expect you have one or more records in sys.indexes which have a data_space_id value greater than 32,767 (the maximum value which can be stored in a smallint variable).
You can check by running:
SELECT SCHEMA_NAME(t.schema_id) [schema_name] ,
t.name AS TableName,
ix.name AS IndexName,
ix.data_space_id
FROM sys.tables t
INNER JOIN sys.indexes ix ON t.object_id = ix.object_id
WHERE ix.type > 0
AND ix.is_primary_key = 0
AND ix.is_unique_constraint = 0
AND t.is_ms_shipped = 0
AND ix.data_space_id > 32767
ORDER BY SCHEMA_NAME(t.schema_id),
t.name,
ix.name
This will return any indexes with this problem. I can see two ways to fix your query:
Omit the FILEGROUP_NAME() call from the original cursor definition and subsequent FETCH calls - it doesn't look like you use it for anything later on, so there's no need for it to be included.
Amend the WHERE clause of the original cursor definition to exclude any indexes with data_space_id values greater than 32767. Note that this approach will mean some indexes are not included in your cursor, but these will only be the ones which have been causing it to fail anyway.
As for why SQL Server allows values greater than 32767 in sys.indexes.data_space_id while FILEGROUP_NAME() requires a smallint parameter, I have no idea - maybe someone else can enlighten us on this?

Random Number Generator - Create a matrix of random numbers where the values in each row sum to X in T-SQL?

How to generate a matrix of random numbers where the values in each row add up to X in T-SQL?
The solution matrix should be dynamic:
User can specify number of columns to be returned in the result
User can specify number of rows to be returned in the result
Each row must sum to X (eg. 1)
create proc RandomNumberGenerator
(
#rows int
, #cols int
, #rowsumtotal float
)
as
....
First create a UDF...
CREATE FUNCTION [dbo].[_ex_fn_SplitToTable] (#str varchar(5000), #sep varchar(1) = null)
RETURNS #ReturnVal table (n int, s varchar(5000))
AS
/*
Alpha Test
-----------
select * from [dbo].[_ex_fn_SplitToTable_t2]('a b c d e',' ')
*/
BEGIN
if #sep = ' '
begin
set #sep = CHAR(167)
set #str = REPLACE(#str,' ',CHAR(167))
end
declare #str2 varchar(5000)
declare #sep2 varchar(1)
if LEN(ISNULL(#sep,'')) = 0
begin
declare #i int
set #i = 0
set #str2 = ''
declare #char varchar(1)
startloop:
set #i += 1
--print #i
set #char = substring(#str,#i,1)
set #str2 = #str2 + #char + ','
if LEN(#str) <= #i
goto exitloop
goto startloop
exitloop:
set #str2 = left(#str2,LEN(#str2) - 1)
set #sep2 = ','
--print #str2
end
else
begin
set #str2 = #str
set #sep2 = #sep
end
;WITH Pieces(n, start, stop) AS (
SELECT 1, 1, CHARINDEX(#sep2, #str2)
UNION ALL
SELECT n + 1, stop + 1, CHARINDEX(#sep2, #str2, stop + 1)
FROM Pieces
WHERE stop > 0
)
insert into #ReturnVal(n,s)
SELECT n,
SUBSTRING(#str2, start, CASE WHEN stop > 0 THEN stop-start ELSE 5000 END) AS s
FROM Pieces option (maxrecursion 32767)
RETURN
END
GO
Then, create this stored proc...
CREATE PROC [dbo].[RandomNumberGenerator]
(
#Pockets int = 6,
#SumTo float = 100,
#i_iterations int = 100
)
/*
ALPHA TEST
----------
exec RandomNumberGenerator 10, 100, 500
*/
AS
if object_id('tempdb..#_Random_00') is not null drop table #_Random_00
declare #columnstring varchar(max) = (SELECT REPLICATE('c ',#Pockets) as Underline)
print #columnstring
if object_id('tempdb..#_Random_columns') is not null drop table #_Random_columns
select s+CONVERT(varchar,dbo.PadLeft(convert(varchar,n),'0',3)) cols
into #_Random_columns
from [dbo].[_ex_fn_SplitToTable](#columnstring,' ') where LEN(s) > 0
-- ===========================
--select * from #_Random_columns
-- ===========================
declare #columns_sql varchar(max)
set #columns_sql =
(
select distinct
stuff((SELECT distinct + cast(cols as varchar(50)) + ' float, '
FROM (
select cols
from #_Random_columns
) t2
--where t2.n = t1.n
FOR XML PATH('')),3,0,'')
from (
select cols
from #_Random_columns
) t1
)
set #columns_sql = LEFT(#columns_sql,LEN(#columns_sql) - 1)
print #columns_sql
declare #sql varchar(max)
set #sql = 'if object_id(''tempdb..##_proctable_Random_01'') is not null drop table ##_proctable_Random_01 '
print #sql
execute(#sql)
set #sql = 'create table ##_proctable_Random_01 (rowid int,' + #columns_sql + ')'
print #sql
execute(#sql)
declare #TotalOfRand float
declare #i_inner int
declare #i_outer int
set #i_outer = 0
start_outer:
set #i_outer = #i_outer + 1
set #i_inner = 0
declare #sumstring varchar(max)
set #sumstring = ''
start_inner:
set #i_inner = #i_inner+1
set #sumstring = #sumstring + CONVERT(varchar, rand()) + ','
if #i_inner >= #Pockets
goto exit_inner
goto start_inner
exit_inner:
set #TotalOfRand = ( select sum(convert(float,s)) from dbo._ex_fn_SplitToTable(#sumstring,',') )
declare #sumstring_quotient varchar(max)
set #sumstring_quotient = replace(#sumstring,',', '/' + Convert(varchar,#TotalOfRand) + '*' + convert(varchar,#SumTo) + ',')
set #sumstring_quotient = LEFT(#sumstring_quotient,len(#sumstring_quotient) - 1)
print #sumstring_quotient
set #sql = '
insert into ##_proctable_Random_01
select
( select count(*) + 1 from ##_proctable_Random_01 ) rowid,' + #sumstring_quotient
execute(#sql)
if #i_outer >= #i_iterations
goto exit_outer
goto start_outer
exit_outer:
select * from ##_proctable_Random_01
drop table ##_proctable_Random_01
GO

How do I get the return value from a CASE statement as a dynamic SQL query?

DECLARE #command = 'SELECT CASE WHEN ( SELECT COUNT(*)
FROM [table] WITH ( NOLOCK )
WHERE DATEDIFF(minute, systemupdatedtimestamp, GETDATE()) < 10
) > 0 THEN 0
ELSE 1
END'
Now I need to get the 'return value' of the above command (0 or 1).
EXEC(#commnad)
How do I get the return value from the above?
I tried
SET #ReturnValue = EXEC(#command)
but no luck.
use sp_executesql
in your case it is something like:
declare #myOut bit
declare #SQLString nvarchar(500)
set #SQLString = N'SELECT #myOutValue = CASE WHEN ( SELECT COUNT(*)
FROM [table] WITH ( NOLOCK )
WHERE DATEDIFF(minute, systemupdatedtimestamp, GETDATE()) < 10
) > 0 THEN 0
ELSE 1
END'
declare #ParmDefinition nvarchar(500)
set #ParmDefinition = N'#myOutValue bit OUTPUT'
EXECUTE sp_executesql #SQLString, #ParmDefinition, #myOutValue = #myOut OUTPUT
select #myOut
Update:
To follow up on you comment. If you do not want to modify the original string containing your sql command (e.g. it is used in other places etc) you can wrap that command inside a new string something like:
#SQLString = 'select #myOutValue = (' + #yourOrigSqlCommand + ')'
And call sp_executesql in the same way as above.
I believe this solves your problem.
DECLARE #command nvarchar(max) = 'SELECT CASE WHEN ( SELECT COUNT(*)
FROM [table] WITH ( NOLOCK )
WHERE DATEDIFF(minute, systemupdatedtimestamp, GETDATE()) < 10
) > 0 THEN 0
ELSE 1
END'
exec sp_executesql #command

T-SQL How To Count Of Records For Each Column

I have a table with over 120 columns and need to determine which column is used the least. I tried using sql queries to do this, but found T-SQL a bit simpler.
I tried the following but my count comes out as 0 for every column.
Declare data1 Cursor for select column_name
from information_schema.columns
where table_name = 'repository'
Declare #mField nvarchar(255)
Declare #count int
Open data1;
fetch next from data1 into #mField;
set #count = -1;
while ##fetch_status = 0
begin
select #count = count(#mField)
from repository where tablereference =
'central' and ( #mField!= null )
print #mField+' ' ;
print #count;
Fetch next from data1 into #mField;
end
close data1;
deallocate data1;
You can't count values like this because you are only testing if #mField is NULL. The column name isn't substituted.
COUNT ignores NULLs anyway so if you want to count non-null values, do this:
DECLARE #sql varchar(4000)
SET #sql = 'SELECT COUNT(*) AS Total '
SELECT #sql = #sql + ', COUNT(' + QUOTENAME(column_name) + ') AS ' + QUOTENAME(column_name)
from information_schema.columns
where table_name = 'repository'
SET #sql = #sql + ' FROM repository'
EXEC (#sql)
This queries the table once for all columns
You need to use some dynamic sql in the middle to acheive your aim here.
Declare data1 Cursor for select column_name
from information_schema.columns
where table_name = 'repository'
Declare #mField nvarchar(255)
Open data1;
fetch next from data1 into #mField;
while ##fetch_status = 0
begin
exec ('
declare #count int
select #count = count([' + #mField + '])
from repository where tablereference =
''central'' and ( [' + #mField + '] is not null)
if #count < 10
begin
print ''' + #mField + ' '' ;
print #count;
end
')
Fetch next from data1 into #mField;
end
close data1;
deallocate data1;
Your count(#mField) is a count of the litteral value that happens to be in #mField, its not resolving the field name into COUNT(fldBlah), you would need to use dynamic SQL for that.
Declare data1 Cursor FAST_FORWARD for select column_name
from information_schema.columns where table_name = 'repository'
Declare #mField nvarchar(255)
Declare #SQL varchar(1024)
Declare #results table (col_name varchar(128), non_nulls int)
Open data1;
fetch next from data1 into #mField;
while (##FETCH_STATUS = 0) begin
set #SQL = 'SELECT ''' + #mField + ''', count(' + #mField + ') from repository where tablereference = ''central'''
insert #results
exec(#SQL)
Fetch next from data1 into #mField;
end
close data1;
deallocate data1;
select * from #results
For an output like;
col_name non_nulls
[tablereference] 5
[another_col] 1
Where there are 5 non-null values in column tablereference etc
You need to use IS NOT NULL instead of != NULL