I have few tables in my database and I want to count total rows of all those tables based on AppoitmentID for which I use a scalar cursor and a table variable to store some data of those tables based on AppoitmentID. After the end of cursor I count rows of table variable in which I had inserted data using dynamic query in cursor.
But it gives me the following error
Must declare the table variable "#ProcCount".
Is there any other way to get the count of all rows from necessary tables.
Below is my Code :
Create FUNCTION [dbo].[ufn_GetProcedureCount]
(
)
RETURNS INT
AS
BEGIN
-- Declare the return variable here
DECLARE #MenuID bigINT, #TableName VARCHAR(150);
DECLARE #Result int
DECLARE #ProcCount TABLE (AppID INT, WoundId bigINT,TableName varchar(150));
DECLARE #sql nvarchar(2000)
DECLARE #Count int
DECLARE Cur_PendSign Cursor For
select Distinct MenuID,TableName from AppointmentTypeRequiredDocumnet A inner join Menu M on M.ID =A.MenuID where m.MenuGroupID = 8
OPEN Cur_PendSign
FETCH Cur_PendSign INTO #MenuID, #TableName
WHILE ##FETCH_STATUS=0
BEGIN
SET #sql='DECLARE #ProcCount TABLE (AppID INT, WoundId bigINT,TableName varchar(150))'
SET #sql=#sql+'INSERT INTO #ProcCount (AppID,WoundId)
SELECT TOP 1 V.AppointmentID, 1
FROM ['+#TableName+'] V WITH(NOLOCK)'
set #sql=#sql+ 'select count(*) from #ProcCount;'
--set #sql=#sql+ 'DECLARE #Count int'
EXECUTE sp_executesql #sql
FETCH Cur_PendSign INTO #MenuID, #TableName
END
CLOSE Cur_PendSign
DEALLOCATE Cur_PendSign
--set #Result = select count(*) from #ProcCount
RETURN #Result
END
There are two issues with the script.
First: Missing where clause
select Distinct MenuID,TableName from Appointment A.AppointmentID = 8
Second: you need to create persistent table rather than variable table due to limitation of scope as you cant declare variable table outside of EXEC and use it.
This query should work for you. You need to use sp_executesql to execute dynamic queries.
CREATE FUNCTION [dbo].[ufn_GetProcedureCount]
(
)
RETURNS INT
AS
BEGIN
-- Declare the return variable here
DECLARE #Result INT
DECLARE #ProcCount TABLE (
AppID INT,
WoundId BIGINT,
TableName VARCHAR(150)
)
DECLARE #MenuID BIGINT,
#TableName VARCHAR(150)
--Get all table which I need to count rows
DECLARE Cur_PendSign CURSOR FOR
SELECT DISTINCT MenuID, TableName FROM Appointment WHERE AppointmentID = 8
OPEN Cur_PendSign
FETCH Cur_PendSign INTO #MenuID, #TableName
WHILE ##fetch_status = 0
BEGIN
-- Insert require data into #ProcCount using dynamic query
DECLARE #query VARCHAR(255) = 'INSERT INTO #ProcCount (AppID,WoundId,TableName)
SELECT TOP 1 AppointmentID, WoundId, TableName
FROM [' + #TableName + '] WITH(NOLOCK) '
EXECUTE sys.sp_executesql #query
FETCH Cur_PendSign INTO #MenuID, #TableName
END
CLOSE Cur_PendSign
DEALLOCATE Cur_PendSign
--Get Count of all rows from tables
SELECT #Result = COUNT(*) FROM #ProcCount
RETURN #Result
END
Without having a cursor, Loops you can do it with Dynamic coding..
Schema:
(It may be differ with your actual schema)
CREATE TABLE #Appointment (MENUID INT IDENTITY,AppointmentID INT, TableName VARCHAR(20))
INSERT INTO #Appointment
SELECT 1,'TABLE1'
UNION ALL
SELECT 2, 'TABLE2'
UNION ALL
SELECT 8,'TABLE3'
UNION ALL
SELECT 8,'TABLE4'
UNION ALL
SELECT 8,'TABLE5'
Now do like below
DECLARE #QRY VARCHAR(MAX)='';
SELECT #QRY = #QRY+ 'SELECT COUNT(1) AS COUNT_TABLES FROM '+ TableName + ' (NOLOCK)
UNION ALL
' FROM (
SELECT DISTINCT TableName FROM #Appointment A WHERE A.AppointmentID = 8
)A
SELECT #QRY = SUBSTRING(#QRY,1,LEN(#QRY)-11)
SELECT #QRY = '
SELECT SUM(COUNT_TABLES) FROM (
' + #QRY+'
)A'
--PRINT #QRY
EXEC (#QRY)
If you want to check what #QRY contains
/*
SELECT SUM(COUNT_TABLES) FROM (
SELECT COUNT(1) AS COUNT_TABLES FROM TABLE3 (NOLOCK)
UNION ALL
SELECT COUNT(1) AS COUNT_TABLES FROM TABLE4 (NOLOCK)
UNION ALL
SELECT COUNT(1) AS COUNT_TABLES FROM TABLE5 (NOLOCK)
)A
*/
Related
declare #tab_name varchar(100)
declare #col_name varchar(100)
declare #sqlquery nvarchar(max)
declare cursor_table cursor
for
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES --where table_name!='tab'
open cursor_table
fetch next from cursor_table into #tab_name
while ##fetch_status = 0
begin
declare cursor_count cursor
for
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = #tab_name
open cursor_count
fetch next from cursor_count into #col_name
while ##FETCH_STATUS =0
begin
set #sqlquery='
select '+''''+#tab_name+''''+','+''''+ #col_name+''''+',count('+#col_name+') as count from '+#tab_name+' where ISNULL('+#col_name+','''') !='''' '
print #sqlquery
exec sp_executesql #sqlquery
fetch next from cursor_count into #col_name
End
CLOSE cursor_count
DEALLOCATE cursor_count
print #tab_name
fetch next from cursor_table into #tab_name
end
CLOSE cursor_table
DEALLOCATE cursor_table
I would approach it this way if I "needed" to get a count of all null values per column, per table.
This is very inefficient query and may take a while to execute as you are bound to perform multiple full table scans for all non-indexed fields. I would advise, for this exercise, that you limit it to a few tables.
SELECT CommandOrder=1,'DECLARE #TEMP TABLE(TableName NVARCHAR(100), ColumnName NVARCHAR(100), NullRecordCount INT)'
UNION
SELECT CommandOrder=3,
'INSERT #TEMP SELECT '''+S.Name+'.'+T.Name+''','''+C.Name+''', COUNT(*) FROM '+S.Name+'.'+T.Name+' WHERE COALESCE('+C.Name+',NULL)=NULL'
FROM
SYS.Columns C
INNER JOIN SYS.Tables T ON C.object_id = T.object_id
INNER JOIN SYS.Schemas S ON T.schema_id = S.schema_id
UNION
SELECT CommandOrder=4,'SELECT * FROM #TEMP T WHERE NullRecordCount > 0 ORDER BY TableName,ColumnName'
If it is a requirement to minimize it to one cursor at the very least, use this.
If you really have to use cursors, use FAST_FORWARD cursor option.
declare #tab_name varchar(100)
declare #col_name varchar(100)
declare #sqlquery nvarchar(max)
DECLARE #mainTable TABLE(
Id INT IDENTITY(1,1) PRIMARY KEY,
TABLE_NAME Varchar(500)
)
--GET TABLES data into main table
INSERT INTO #mainTable
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
DECLARE #startTables INT = 1
DECLARE #finalTables INT = 0
SELECT #finalTables = MAX(Id) FROM #mainTable
-- Do a while loop over id
WHILE #startTables <= #finalTables
BEGIN
-- Get the table name
SELECT #tab_name = TABLE_NAME FROM #mainTable WHERE Id = #startTables
-- Initialize cursor
declare cursor_count cursor
for
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = #tab_name
open cursor_count
fetch next from cursor_count into #col_name
while ##FETCH_STATUS =0
begin
set #sqlquery='select '+''''+#tab_name+''''+','+''''+ #col_name+''''+',count('+#col_name+') as count from '+#tab_name+' where ISNULL('+#col_name+','''') !='''' '
print #sqlquery
exec sp_executesql #sqlquery
fetch next from cursor_count into #col_name
End
CLOSE cursor_count
DEALLOCATE cursor_count
print #tab_name
SET #startTables = #startTables + 1
END
To use no cursor at all, use this.
declare #tab_name varchar(100)
declare #col_name varchar(100)
declare #sqlquery nvarchar(max)
-- Table stores Id, table name, Query in one go.
DECLARE #secondaryTable TABLE(
Id INT IDENTITY(1,1) PRIMARY KEY,
TABLE_NAME Varchar(500),
Query Varchar(8000)
)
INSERT INTO #secondaryTable
SELECT a.TABLE_NAME, 'select '+''''+a.TABLE_NAME+''''+','+''''+ b.COLUMN_NAME+''''+',count('+b.COLUMN_NAME+') as count from '+a.TABLE_NAME+' where ISNULL('+b.COLUMN_NAME+','''') !='''' '
FROM INFORMATION_SCHEMA.TABLES a INNER JOIN INFORMATION_SCHEMA.COLUMNS b ON a.TABLE_NAME = b.TABLE_NAME
--SELECT * FROM #secondaryTable
DECLARE #startTables INT = 1
DECLARE #finalTables INT = 0
SELECT #finalTables = MAX(Id) FROM #secondaryTable
-- Loop through the table, get the table name and query. Execute the query.
WHILE #startTables <= #finalTables
BEGIN
SELECT #tab_name = TABLE_NAME, #sqlquery = Query FROM #secondaryTable WHERE Id = #startTables
print #sqlquery
exec sp_executesql #sqlquery
print #tab_name
SET #startTables = #startTables + 1
END
I am using SQL Server 2012.
The first part of my query is already answered in this thread. But I also want a second column that will show the corresponding maximum value of that column in its corresponding table.
I have tried this approach: use a function that takes in table name and column name as parameter and return the max value. But it is illegal to use dynamic SQL from a function. Moreover, i cannot seem to call a function from within a SELECT query.
I have also tried using stored procedure, but i cannot figure out how to call it and use it. Please suggest alternative ways to achieve this.
I am new to SQL Server.
Thanks
I think the easiest solution would be stored procedure. As far as I know:
Dynamic SQL can't be placed in functions
Dynamic SQL can't be place in OPENROWSET
I addition, if you write such procedure:
Beware of names containing spaces, qoutes (SQL injection possible)
MAX(column) on non-Indexed columns would require full scan (can be very slow)
Table and column names can be duplicated (placed in differend schemas)
Id duplicates and performance is not a problem, take a look at the following snippet:
CREATE PROC FindMaxColumnValues
#type sysname = '%',
#table sysname = '%'
AS
DECLARE #result TABLE (TableName sysname, ColumnName sysname, MaxValue NVARCHAR(MAX))
DECLARE #tab sysname
DECLARE #col sysname
DECLARE cur CURSOR FOR
SELECT TABLE_NAME TableName, COLUMN_NAME [Column Name]
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE LIKE #type and TABLE_NAME LIKE #table
OPEN cur
FETCH NEXT FROM cur INTO #tab, #col
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #sql nvarchar(MAX) = 'SELECT '+QUOTENAME(#tab,'''')+' [TableName], '+QUOTENAME(#col, '''')+' [ColumnName], MAX('+QUOTENAME(#col)+') FROM '+QUOTENAME(#tab)
INSERT INTO #result EXEC(#sql)
FETCH NEXT FROM cur INTO #tab, #col
END
CLOSE cur
DEALLOCATE cur
SELECT * FROM #result
Samples:
--MAX of INT's
EXEC FindMaxColumnValues 'INT'
--MAX of INT's in tables matching 'TestTab%'
EXEC FindMaxColumnValues 'INT', 'TestTab%'
--MAX of ALL columns
EXEC FindMaxColumnValues
Results:
TableName ColumnName MaxValue
IdNameTest ID 2
TestTable ID 5
TestTable Number 3
TableName ColumnName MaxValue
TestTable ID 5
TestTable Number 3
TableName ColumnName MaxValue
UpdateHistory UpdateTime 2016-07-14 12:21:37.00
IdNameTest ID 2
IdNameTest Name T2
TestTable ID 5
TestTable Name F
TestTable Number 3
You can use the below SP and enhance it per your Need,
CRETE PROCEDURE Getmaxtablecolval
AS
BEGIN
CREATE TABLE #t
(
tablename VARCHAR(50),
columnname VARCHAR(50),
id INT,
counts INT
)
INSERT INTO #t
SELECT table_name [Table Name],
column_name [Column Name],
NULL,
NULL
FROM information_schema.columns
WHERE data_type = 'INT'
BEGIN TRAN
DECLARE #id INT
SET #id = 0
UPDATE #t
SET #id = id = #id + 1
COMMIT TRAN
DECLARE #RowCount INT
SET #RowCount = (SELECT Count(0)
FROM #t)
DECLARE #I INT
SET #I = 1
DECLARE #Counter INT
DECLARE #TName VARCHAR(50)
DECLARE #CName VARCHAR(50)
DECLARE #DynamicSQL AS VARCHAR(500)
WHILE ( #I <= #RowCount )
BEGIN
SELECT #TName = tablename
FROM #t
WHERE id = #I
SELECT #CName = columnname
FROM #t
WHERE id = #I
SET #DynamicSQL = 'Update #T Set Counts = '
+ '(Select ISNull(Max(' + #CName + '), 0) From '
+ #TName + ') Where Id = '
+ CONVERT(VARCHAR(10), #I)
--PRINT #DynamicSQL
EXEC (#DynamicSQL)
SET #I = #I + 1
END
SELECT *
FROM #t
END
go
Getmaxtablecolval
You can create a procedure out of this:
CREATE PROCEDURE GET_COLUMNS_WITH_MAX_VALUE
#COLUMN_TYPE NVARCHAR(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- DUMMY VARIABLE TO COPY STRUCTURE TO TEMP
DECLARE #DUMMY TABLE
(
TABLE_NAME NVARCHAR(50),
COLUMN_NAME NVARCHAR(50),
MAX_VALUE NVARCHAR(MAX)
)
-- CREATE TEMP TABLE FOR DYNAMIC SQL
SELECT TOP 0 * INTO #TABLE FROM #DUMMY
INSERT INTO #TABLE
(TABLE_NAME, COLUMN_NAME)
SELECT TABLE_NAME, COLUMN_NAME
FROM information_schema.columns where data_type = #COLUMN_TYPE
DECLARE #TABLE_NAME VARCHAR(50) -- database name
DECLARE #COLUMN_NAME VARCHAR(256) -- path for backup files
DECLARE db_cursor CURSOR FOR
SELECT TABLE_NAME, COLUMN_NAME
FROM #TABLE
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #TABLE_NAME, #COLUMN_NAME
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #SQL NVARCHAR(MAX) = 'UPDATE #TABLE SET MAX_VALUE = (SELECT MAX([' + #COLUMN_NAME + ']) FROM [' + #TABLE_NAME + ']) '
+ 'WHERE [COLUMN_NAME] = ''' + #COLUMN_NAME + ''' AND TABLE_NAME = ''' + #TABLE_NAME + '''';
PRINT #SQL
EXEC (#SQL)
FETCH NEXT FROM db_cursor INTO #TABLE_NAME, #COLUMN_NAME
END
CLOSE db_cursor
DEALLOCATE db_cursor
SELECT * FROM #TABLE
DROP TABLE #TABLE
END
GO
Usage:
EXEC GET_COLUMNS_WITH_MAX_VALUE 'INT'
Results:
TABLE1 ID 50
TABLE2 ID 100
TABLE3 CarID 20
TABLE4 StudentID 30
I have a function that will return all items in all firms.Table names should be parametric.But I could not create a view from that function.Because I can not return a table.The returned value is a string. Please help.Thanks.
GO
IF OBJECT_ID(N'dbo.ufnGetContactInformation', N'TF') IS NOT NULL
DROP FUNCTION dbo.ufnGetContactInformation;
GO
CREATE FUNCTION dbo.ufnGetContactInformation()
RETURNS #retContactInformation TABLE
(
-- Columns returned by the function
firm nvarchar(50) NULL
)
AS
BEGIN
DECLARE #referans AS INT, #NRP AS INT
DECLARE #TABLE AS NVARCHAR(MAX)
SET #TABLE = ''
DECLARE YourCursorNameHere CURSOR READ_ONLY
FOR
select c1.NR, C2.NR
from L_caPIFIRM c1 WITH(nolock)
INNER JOIN L_CAPIPERIOD C2 WITH(nolock) ON C1.NR=C2.FIRMNR
OPEN YourCursorNameHere
FETCH NEXT FROM YourCursorNameHere INTO #referans, #NRP
WHILE ##FETCH_STATUS = 0
BEGIN
IF #TABLE = ''
SET #TABLE= 'SELECT FIRM=' + str(#referans) +', CODE FROM LG_' + SUBSTRING(('00'+ LTRIM(STR(#referans))),LEN(('00'+ LTRIM(STR(#referans))))-2,3)+ '_ITEMS'
ELSE
SET #TABLE= #TABLE + ' UNION SELECT FIRM=' + str(#referans) +', CODE FROM LG_' + SUBSTRING(('00'+ LTRIM(STR(#referans))),LEN(('00'+ LTRIM(STR(#referans))))-2,3)+ '_ITEMS'
FETCH NEXT FROM YourCursorNameHERE INTO #referans,#NRP
END
-- EXEC( #TABLE)
CLOSE YourCursorNameHere
DEALLOCATE YourCursorNameHere
--BEGIN
-- INSERT INTO select
-- END
RETURN;
END;
GO
Try to use dynamic sql .I didnt check it but maybe this is the way to do it...
RETURNS #retContactInformation varchar(max) -- not table
.
.
DECLARE #sql nvarchar(max)
DECLARE #sqlx nvarchar(max)=dbo.ufnGetContactInformation()
set #sql='CREATE VIEW [aaa]
AS
'+ #sqlx+''
EXECUTE sp_executesql #SQL
instead of cursor try while loop
CREATE TABLE #tempo (id INT IDENTITY (1,1),c1nr varchar(10),c2nr varchar(10))
insert into #tempo
select c1.NR, C2.NR
from L_caPIFIRM c1 WITH(nolock)
INNER JOIN L_CAPIPERIOD C2 WITH(nolock) ON C1.NR=C2.FIRMNR
DECLARE #i int = (SELECT count(*) FROM #tempo)
DECLARE #id int=1
WHILE #i!=0
BEGIN
SELECT #referans=c1nr,
#table =IIF ((#TABLE = ''),
'SELECT FIRM=' + str(#referans) +', CODE FROM LG_' + SUBSTRING(('00'+ LTRIM(STR(#referans))),LEN(('00'+ LTRIM(STR(#referans))))-2,3)+ '_ITEMS',
#TABLE + ' UNION SELECT FIRM=' + str(#referans) +', CODE FROM LG_' + SUBSTRING(('00'+ LTRIM(STR(#referans))),LEN(('00'+ LTRIM(STR(#referans))))-2,3)+ '_ITEMS' )
from #tmpo
where id=#id
set #id=#id+1
set #i=#i-1
END
I am trying to write a windows service, which will send automatic emails. all the tables which require email sending have common columns 'templateid' and 'emailstatus'. I want to iterate through all the tables and get the tables which has column name 'templateid'.
Now that i have the list of tables with column name 'templateid' get the data from each table whose email status is 'false' and save it in a temporary table.
if 'table1' has 4 rows of data, the temporary table should have 4 rows. after iterating through the next table the row collection should be added to the same temporary table.
IF (SELECT object_id('TempDB..#TEMPTABLE')) IS NOT NULL
BEGIN
DROP TABLE #TEMPTABLE
END
CREATE TABLE #TEMPTABLE(
[ID] INTEGER IDENTITY(1,1) NOT NULL,
[TABLE_NAME] VARCHAR(1000)
)
INSERT INTO #TEMPTABLE(TABLE_NAME)
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'TEMPLATEID'
SELECT * FROM #TEMPTABLE
DECLARE #ROWCOUNT INT
SET #ROWCOUNT = (SELECT COUNT(ID) FROM #TEMPTABLE)
DECLARE #I INT
SET #I=1
WHILE(#I<=#ROWCOUNT)
BEGIN
DECLARE #TABLENAME VARCHAR(500)
SELECT #TABLENAME=TABLE_NAME FROM #TEMPTABLE WHERE ID=#I
EXEC('SELECT * FROM '+#TABLENAME)
SET #I=#I+1
END
i found the above query which is giving me all the tables. after that i am clueless how to proceed further as i am not good with sql server.
Not sure you are still looking for an answer but the following code will give you a temporary table with just the tables that have a column named 'templateid'. From here you would need a cursor as Tanner suggested to loop through each table and then insert records from each table (into your final target table) where email status = 'false'.
Here is the code that gets you the temp tables with columns named 'templateid' along with a sample for your cursor:
declare #max_tables int
declare #max_columns int
declare #sql nvarchar(400)
declare #x int
declare #y int
declare #table varchar(50)
declare #columns varchar(800)
declare #tablename varchar(100)
create table #c ([Table] varchar(50),[Columns] varchar(800))
select ROW_NUMBER() OVER(ORDER BY name) AS Row, name
into #table_list
from sys.objects
where type_desc = 'USER_TABLE'
order by name
set #max_tables = (select count(*) from sys.objects where type_desc = 'USER_TABLE')
set #y = 0
while #y < #max_tables
begin
set #y = #y + 1
set #table = (select name from #table_list where row = #y)
create table #t (c int)
set #sql = 'select count(*) as c from Information_schema.Columns where table_name = ''' + #table + ''''
insert into #t exec sp_executesql #sql
set #max_columns = (select top 1 c from #t)
DROP TABLE #t
set #x = 0
set #columns = ''
while #x < #max_columns
begin
set #x = #x + 1
set #columns = #columns + (select column_name from Information_schema.Columns where table_name = #table and ordinal_position = #x)
if #x < #max_columns set #columns = #columns + ', '
end
insert into #c select #table,#columns
end
select * into #tables from #c c
where c.Columns like '%templateid%'
declare my_cursor cursor for
select table from #t
open my_cursor
fetch next from my_cursor into #tablename
while ##fetch_status = 0
begin
--do something here to retrieve your data from each table and
--insert into target table
end
close my_cursor
deallocate my_cursor
DROP TABLE #c,#tables,#table_List
Is there a generic stored procedure to audit the table. I have actually made one but I don't think its efficient and the stored procedure is quite long. If someone knows a better way to do it then please help me out...!
This is my table trigger.
ALTER TRIGGER [dbo].[Trigger3]
ON [dbo].[UserInfo]
AFTER Update
AS
BEGIN
SET NOCOUNT ON;
DECLARE #TABLENAME VARCHAR(50)
DECLARE #var varbinary
SELECT * INTO #TEMPINSERTED FROM inserted
SELECT * INTO #TEMPDELETED FROM deleted
SET #var = COLUMNS_UPDATED()
EXEC TetsProc #TEMPINSERTED, #TEMPDELETED, ##PROCID, #var
DROP TABLE #TEMPINSERTED
DROP TABLE #TEMPDELETED
END
This is my stored procedure
ALTER PROCEDURE [dbo].[TetsProc]
( #insertTable varchar(max),
#deleteTable varchar(max),
#IDZ varchar(max),
#var1 varbinary
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #TABLE AS TABLE (COL_NAME NVARCHAR(MAX))
DECLARE #idTable INT
SELECT #idTable = T.id
FROM sysobjects P JOIN sysobjects T ON P.parent_obj = T.id
WHERE P.id = #IDZ
declare #q1 nvarchar(max),#q2 nvarchar(max)
set #q1 = 'select * from ' + #insertTable
set #q2 = 'select * from ' + #deleteTable
DECLARE #TABLENAME NVARCHAR(250)
SELECT #TABLENAME = OBJECT_NAME(parent_obj)
FROM sysobjects WHERE ID = #IDZ
----RETURN COLUMNS IF THEY ARE UPDATED----
SELECT #idTable = T.id
FROM sysobjects P JOIN sysobjects T ON P.parent_obj = T.id
WHERE P.id = ##procid
DECLARE #Columns_UpdateD VARCHAR(50)
SELECT #Columns_Update = ISNULL(#Columns_Updated + ', ', '') + name
FROM syscolumns
WHERE id = #idTable
AND CONVERT(VARBINARY,REVERSE(#var1)) & POWER(CONVERT(BIGINT, 2), colorder - 1) > 0
select status into #TmpcolumnsUpdated from dbo.ParseByComma(#Columns_UpdateD)
DECLARE #QRY1 NVARCHAR(MAX)
DECLARE #QRY2 NVARCHAR(MAX)
declare #column_name varchar(50)
DECLARE cursorColumnName CURSOR FOR
select status from #TmpcolumnsUpdated
OPEN cursorColumnName
FETCH NEXT FROM cursorColumnName INTO #column_name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #QRY1= 'SELECT '+#column_name + ' FROM '+ #insertTable
SET #QRY2= 'SELECT '+#column_name + ' FROM ' + #deleteTable
DECLARE #tab AS TABLE (OLD_COL VARCHAR(10))
DECLARE #tab1 AS TABLE (NEW_COL VARCHAR(10))
INSERT into #tab EXECUTE sp_executesql #QRY2
INSERT into #tab1 EXECUTE sp_executesql #QRY1
DECLARE #OLD_VALUE VARCHAR(MAX)=(SELECT OLD_COL FROM #tab)
DECLARE #NEW_VALUE VARCHAR(MAX)=(SELECT NEW_COL FROM #tab1)
IF(#OLD_VALUE!=#NEW_VALUE)
BEGIN
INSERT INTO UpdateInfo (Table_Name,Col_Name,Old_Value,New_Value,Time)
(
SELECT
#TABLENAME,
#column_name,
#OLD_VALUE,
#NEW_VALUE,
GETDATE()
)
SELECT * FROM UpdateInfo
END
DELETE FROM #tab
DELETE FROM #tab1
FETCH NEXT FROM cursorColumnName INTO #column_name
END
CLOSE cursorColumnName
DEALLOCATE cursorColumnName
drop table #TmpcolumnsUpdated
END
Looks like a sure way to drag down the performance of your server.
If you are using SQL Server 2012, I'd recommend you to check out Sql Server Audit instead.
If you have to stick with your mechanism, at the very least lose the cursor in the PROC.