Could you please help me rewrite the following CP so when it reads from the file to remove any other characters except numbers:
what it does is read a file for example block.txt and addes each line into the table.
USE [db_Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Cp_ImportBlackList]
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION Acbc
DECLARE #command nvarchar(max)
DECLARE #delcommand varchar(200)
DECLARE #txtfile nvarchar(200)
DECLARE #line nvarchar(2)
DECLARE #andreas nvarchar(200)
set #line='\n'
DECLARE #isExists INT
DECLARE #tempcol int
DECLARE MyCursor cursor fast_forward for
Select Users_ID from Prj_Users
open MyCursor
fetch next from MyCursor
into #tempcol
while ##fetch_status = 0
begin
set #txtfile = 'c:\BlackList\ ' + LTRIM(RTRIM(str(#tempcol))) + '.txt'
exec master.dbo.xp_fileexist #txtfile,
#isExists OUTPUT
if (#isExists =1)
begin
BEGIN TRY
BEGIN TRANSACTION ad
set #command=' BULK INSERT Prj_TempBlackList FROM ''' + #txtfile + ''''
set #command += ' WITH( ROWTERMINATOR = '''+ #line +''' )'
print #command
EXECUTE(#command)
delete Prj_TempBlackList where Tell in(select [BLList_TEll] from prj_BlackList where [BLList_UserID] = #tempcol)
insert into prj_BlackList select DISTINCT Tell,#tempcol from Prj_TempBlackList where Tell not in(select [BLList_TEll] from prj_BlackList where [BLList_UserID] = #tempcol)
delete from Prj_TempBlackList
set #delcommand ='del ' + #txtfile
exec xp_cmdshell #delcommand
print 'end'
COMMIT TRANSACTION ad
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION ad
SELECT ERROR_Message() AS ErrorNumber;
END CATCH
end
else
print 'no'
fetch next from MyCursor
into #tempcol
end
close MyCursor
deallocate MyCursor
set #txtfile = 'c:\BlackList\block.txt'
exec master.dbo.xp_fileexist #txtfile,
#isExists OUTPUT
if (#isExists =1)
begin
BEGIN TRY
BEGIN TRANSACTION ada
set #command=' BULK INSERT Prj_TempBlackList FROM ''' + #txtfile + ''''
set #command += ' WITH( ROWTERMINATOR = '''+#line+''' )'
EXECUTE(#command)
delete Prj_TempBlackList where Tell in(
select [BLList_TEll] from prj_BlackList where [BLList_UserID] is null)
insert into prj_BlackList SELECT DISTINCT Tell,null from
Prj_TempBlackList where Tell not in(
select [BLList_TEll] from prj_BlackList where [BLList_UserID] is null)
delete from Prj_TempBlackList
set #delcommand ='del ' + #txtfile
exec xp_cmdshell #delcommand
print 'yes'
COMMIT TRANSACTION ada
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION ada
SELECT ERROR_Message() AS ErrorNumber;
END CATCH
end
COMMIT TRANSACTION Acbc
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION Acbc
END CATCH
END
Try to avoid CURSORs and LOOPs!
This approach does it on the fly, but you really should think about if TSQL is the right tool...
DECLARE #tbl TABLE(ID INT IDENTITY, EvilString NVARCHAR(100));
INSERT INTO #tbl(EvilString) VALUES('ab23cd56jkl'),(' adfhasd l h45 hagf 78 l 9');
WITH RunningNumbers AS
(
SELECT ROW_NUMBER() OVER(ORDER BY A) AS Nmbr
FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblA(A)
,(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblB(B)
,(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblC(C)
,(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblD(D)
,(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblE(E)
,(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblF(F)
)
,SingleChars AS
(
SELECT tbl.ID,rn.Nmbr,SUBSTRING(tbl.EvilString,rn.Nmbr,1) AS Chr
FROM #tbl AS tbl
CROSS APPLY (SELECT TOP(LEN(tbl.EvilString)) Nmbr FROM RunningNumbers) AS rn
)
SELECT ID,EvilString
,(
SELECT '' + Chr
FROM SingleChars AS sc
WHERE sc.ID=tbl.ID AND ASCII(Chr) BETWEEN 48 AND 57
ORDER BY sc.Nmbr
FOR XML PATH('')
) AS GoodString
FROM #tbl As tbl
The result
ID EvilString GoodString
1 ab23cd56jkl 2356
2 adfhasd l h45 hagf 78 l 9 45789
Related
I have created a stored procedure (shown below) in SQL Server and tried to include a Rollback Transaction as I need to have a "stored procedure that has a transaction around it, so that if/when it fails all inserts will be rolled back."
I am unsure if this work or not, or will work, I cannot test yet as only developing locally, but wondered if someone wouldn't mind looking over the Rollback Transaction part of the stored procedure and advise if on the right path?
USE AutomatedTesting
GO
ALTER PROCEDURE [dbo].[spInsertTestCases]
(#AddedTFS INT,
#Scenario NVARCHAR(500),
#TargetTableName NVARCHAR(100),
#TargetFieldName NVARCHAR(100),
#ExpectedResult NVARCHAR(100),
#TargetTableDBName NVARCHAR(100),
#TargetTableSchema NVARCHAR(100),
#TargetFieldIsDateTime NVARCHAR(1),
#TestCaseIdentifiers dbo.TestCaseIdentifiers READONLY ) -- can only be READONLY. meaning you cannot amend the param
/* #TestCaseIdentifiers var will be prepopulated
TestDataIdentifiersNEW is a custom data type which has fields (TestSequence ColumnName ColumnValue IsAlphaNumeric)
so stored procedure is called like:
EXEC [dbo].[spTest_UserDefinedDatatype] 'param1','param2' #temp_testdata
#temp_testdata will already be defined and popualted(INSERT INTO ) before exec to add in 1 to many rows.
for example:
ColumnName ColumnValue
PATIENTID 123456
SOURCESYS PAS
in simple terms above EXEC is:
EXEC [dbo].[spTest_UserDefinedDatatype] 'param1','param2' 'PATIENTID 123456'
'SOURCESYS PAS'
*/
AS
BEGIN TRY
BEGIN TRANSACTION
BEGIN
--DECLARE #TableNameUpdate SYSNAME = #TargetTableName
--DECLARE #CDI SYSNAME = REPLACE(#TargetTableName,'CDO','CDI') -- so if targettablename param is CDO then swap it to CDI. why?
DECLARE #sql VARCHAR(MAX) = ' INSERT INTO [dbo].[TestCasesIdentifier] ([TestCaseId], [TestCaseSequence], [FieldName], [FieldValue], [AlphaNumeric]) VALUES '
DECLARE #i INT = 1
DECLARE #TableNameUpdate SYSNAME = #TargetTableName
DECLARE #CDI SYSNAME = REPLACE(#TargetTableName,'CDO','CDI')
DECLARE #ColName SYSNAME
DECLARE #Ret NVARCHAR(256)
DECLARE #sql2 NVARCHAR(MAX)
DECLARE #TestCaseID INT = -1 --does this need default variable?
DECLARE #ErrorCode INT = ##error
DECLARE #TestSequence INT
DECLARE #ColumnName VARCHAR(100)
DECLARE #ColumnValue VARCHAR(100)
DECLARE #IsAlphaNumeric BIT
DECLARE #TableTestSequence INT = ISNULL((SELECT MAX([TableTestSequence]) + 1 FROM TestCases WHERE #TargetTableName = [TargetTableName]), 1)
-- INSERT into TestCases. 1 record
-- An assumption that a number of fields will have defaults on them - if not, extra fields will need adding
INSERT INTO [dbo].[TestCases] ([AddedTFS], [TableTestSequence], [Scenario],
[TargetTableName], [TargetFieldName], [ExpectedResult],
[TargetTableDBName], [TargetTableSchema], [TargetFieldIsDateTime])
VALUES (#AddedTFS, -- AddedTFS (The TFS Number of the Development carried out)
ISNULL((SELECT MAX([TableTestSequence]) + 1 -- TableTestSequence (Generates the next Sequence Number for a Table)
FROM TestCases -- if table doesnt exist in TestCases then sets to 1
WHERE #TargetTableName = [TargetTableName]), 1),
#Scenario, -- Scenario (A description of the scenario use GIVEN and WHERE)
#TargetTableName, -- TargetTableName (References the Target Table entered at the top of this SQL - SET #TableName = 'CDO_APC_ELECTIVE_ADMISSION_LIST')
#TargetFieldName, -- TargetFieldName (The Field in which we want to test)
#ExpectedResult, -- ExpectedResult (The expected output/result of the field in which we want to test)
#TargetTableDBName, -- The DB to be used
#TargetTableSchema, -- the schema to be used
#TargetFieldIsDateTime) ---- 1 = Yes, 0 = No (Is Target field a datetime field)
-- Grab the identity value just generated by the last statement and the last error code generated
-- in order to reference TestCases PK when adding to TestCaseIdentifiers
SELECT #TestCaseID = SCOPE_IDENTITY(), #ErrorCode = ##error
IF #ErrorCode = 0 --OR #TestCaseID <> -1 -- #ErrorCode <> 0 if error then back out testcases INSERT? surely should use BEGIN/ROLLBACK tran
--IF #ErrorCode = 0 OR #TestCaseID <> -1
-- If there was no error creating the TestCase record, create the records for the WHERE clause
BEGIN
/*
rollback insert if no matching records
rollback insert if SQL returns more than 1 record
return error message to user
*/
SELECT
ic.index_column_id, c.name
INTO #tmp
FROM sys.indexes i
JOIN sys.index_columns ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
JOIN sys.columns c ON c.column_id = ic.column_id
AND c.object_id = ic.object_id
JOIN sys.tables t ON c.object_id = t.object_id
WHERE t.name = #CDI
AND i.is_primary_key = 1
IF (SELECT COUNT(*) FROM #TestCaseIdentifiers) = 0
--IF #PKValues IS NULL
BEGIN
WHILE #i <= (SELECT COUNT(*) FROM #tmp)
BEGIN
SELECT #ColName = [name]
FROM #tmp
WHERE index_column_id = #i
-- if #expectedvalue IS NULL
SET #sql2 = 'SELECT TOP 1 #RetvalOut = ' + QUOTENAME(#ColName) + ' FROM ' + QUOTENAME(#CDI) + ' ORDER BY NEWID()'
-- else
-- SET #sql2 = ''
EXECUTE sp_executesql #command = #sql2, #ParmDefinition = N'#RetvalOut NVARCHAR(MAX) OUTPUT', #retvalOut = #Ret OUTPUT
SET #sql += '(' + CONVERT(VARCHAR(100),#TestCaseID) + ',' + CONVERT(VARCHAR(10),#i) + ',''' + #ColName + ''',''' + #Ret + ''',1),'
SET #i+=1
SELECT #sql = REVERSE(SUBSTRING(REVERSE(#sql),2,8000))
PRINT #sql
EXEC #sql
END
END
ELSE
BEGIN
--PRINT 'got here'
DECLARE csr_TestCaseIdentifierInsert CURSOR FOR
SELECT [TestSequence],[ColumnName],[ColumnValue],[IsAlphaNumeric]
FROM #TestCaseIdentifiers
ORDER BY [TestSequence]
OPEN csr_TestCaseIdentifierInsert
FETCH NEXT FROM csr_TestCaseIdentifierInsert INTO #TestSequence, #ColumnName, #ColumnValue, #IsAlphaNumeric
WHILE ##fetch_status = 0
BEGIN
INSERT INTO [dbo].[TestCasesIdentifier]
([TestCaseId],
[TestCaseSequence],
[FieldName],
[FieldValue],
[AlphaNumeric])
VALUES
(#TestCaseID, #TestSequence, #ColumnName, #ColumnValue,#IsAlphaNumeric)
FETCH NEXT FROM csr_TestCaseIdentifierInsert INTO #TestSequence, #ColumnName, #ColumnValue, #IsAlphaNumeric
END
CLOSE csr_TestCaseIdentifierInsert
DEALLOCATE csr_TestCaseIdentifierInsert
END -- loop to add records to testcasesidentifier
END
END
COMMIT
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
ROLLBACK TRAN
DECLARE #ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE()
DECLARE #ErrorSeverity INT = ERROR_SEVERITY()
DECLARE #ErrorState INT = ERROR_STATE()
-- Use RAISERROR inside the CATCH block to return error
-- information about the original error that caused
-- execution to jump to the CATCH block.
RAISERROR (#ErrorMessage, #ErrorSeverity, #ErrorState);
END CATCH
You are almost there. I usually wrap the stored proc code within a BEGIN..END block as well, then next comes the most important part: you must add SET XACT_ABORT ON; before your TRY..CATCH and BEGIN TRAN, as SQL Server defaults the XACT_ABORT to OFF. Otherwise not everything will be rolled back.
Example setup:
CREATE PROCEDURE dbo.uspMyTestProc
AS
BEGIN
SET NOCOUNT, XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION;
-- Do your magic stuff here before committing...
COMMIT;
END TRY
BEGIN CATCH
IF ##trancount > 0
ROLLBACK TRANSACTION;
-- Add extra error logging here if you want...
END CATCH;
END;
GO
Also, if you want to add a possible stacktrace if you are using nested procedures et cetera you might want to consider using a generic error handler à la Erland Sommerskog. We adapted this approach completely. See for more details How to handle Transaction in Nested procedure in SQL server?
Since Transact-SQL does not allow for construction like select * from exec ..,
sometimes it is very time consuming when we have to call dynamic query or other stored procedure and save output records in the table. We have to look for column names, data types and length in proper order etc. etc.
I prepared the procedure which is doing it automatically: just call UDP_DynSQLToTable with code to execute and table name to store output.
Procedure also works with temporary tables, but local temp tables have to be created before call, with any structure (will be altered by procedure).
Example of usage:
create table #CurrentUsers (dummy_field bit)
exec UDP_DynSQLToTable N'sp_who', '#CurrentUsers'
if exists (select 1 from #CurrentUsers where name='MyBoss') ...
I did not test it so intensively, so use it on you own responsibility and any comments or improvements are welcome.
Regards
create procedure UDP_DynSQLToTable
#sqlcode nvarchar(max),
#table nvarchar(2048),
#overwrite bit = 0
as
begin
set nocount on
/*
exec dbo.UDP_DynSQLToTable 'sp_who', 'myTable', 1 select * from myTable drop table myTable
*/
declare
#cmd nvarchar(max)='',
#dropcols nvarchar(max)='',
#createsql nvarchar(max),
#fieldList nvarchar(max),
#altersql nvarchar(max),
#sqltable nvarchar(max)
select #table=ltrim(rtrim(isnull(#table,'')))
begin try
if len(#table)=0
begin
print object_name(##procid)+': missing table name'
return
end
if left(#table,1)='[' and right(#table,1)=']'
select
#sqltable=#table,
#table=substring(#table,2,len(#table)-2)
else
select #sqltable='['+#table+']'
if (left(#table,1)='#' and left(#table,2)!='##')
begin
if object_id('tempdb..'+#table) is null
begin
print object_name(##procid)+': #table '+#table+' must be created (any structure) before call this proc'
return -4
end
else
begin
select #cmd = 'if (select count(*) from '+#sqltable+') > 0 delete from '+#sqltable
exec sp_executesql #cmd
if not exists (select name from tempdb.sys.columns where object_id=object_id('tempdb..'+#table) and name='dummy___field')
begin
select #cmd = 'alter table '+#sqltable+' add dummy___field bit'
exec sp_executesql #cmd
end
if exists (select name from tempdb.sys.columns where object_id=object_id('tempdb..'+#table) and name!='dummy___field')
begin
select #dropcols = 'alter table '+#sqltable+' drop column '
select #dropcols = #dropcols+name+','
from tempdb.sys.columns where object_id=object_id('tempdb..'+#table) and name!='dummy___field'
select #dropcols=left(#dropcols,len(#dropcols)-1)
exec sp_executesql #dropcols
end
end
end
else if OBJECT_ID(case when left(#table,2)='##'then 'tempdb.' else '' end +#table) is not null
begin
if #overwrite=0
begin
print object_name(##procid)+': object '+#table+' already exists'
return -2
end
else
begin
select #cmd = 'drop table '+#sqltable
exec sp_executesql #cmd
end
end
select #createsql = 'create table '+#sqltable+' ('+char(13)
select #fieldList = ''
select #altersql = 'alter table '+#sqltable+' add '
select
#createsql=#createsql+char(9)+isnull(name,'column_'+convert(nvarchar,column_ordinal))+' '+system_type_name+' '+
case when isnull(is_identity_column,0)=1 then 'IDENTITY ' else '' end +
case when isnull(is_part_of_unique_key,0)=1 then 'UNIQUE ' else '' end+
case when isnull(is_nullable,1)=0 then 'NOT NULL ' else '' end +','+char(13),
#fieldList=#fieldList+name+',',
#altersql=#altersql++char(9)+isnull(name,'column_'+convert(nvarchar,column_ordinal))+' '+system_type_name+' '+
case when isnull(is_identity_column,0)=1 then 'IDENTITY ' else '' end +
case when isnull(is_part_of_unique_key,0)=1 then 'UNIQUE ' else '' end+
case when isnull(is_nullable,1)=0 then 'NOT NULL ' else '' end +','+char(13)
from
(
select top 1000000
column_ordinal, name, system_type_name, is_identity_column, is_nullable, is_part_of_unique_key
from
sys.dm_exec_describe_first_result_set(#sqlcode, null, null) order by column_ordinal
) a
print #createsql
select #altersql=left(#altersql,len(#altersql)-2)
select #createsql=left(#createsql,len(#createsql)-2)+char(13)+char(9)+')'
select #fieldList=left(#fieldlist,len(#fieldlist)-1)
if left(#table,2)='##' or left(#table,1)!='#'
exec sp_executesql #createsql
else
begin
exec sp_executesql #altersql
select #cmd = 'alter table '+#sqltable+' drop column dummy___field'
exec sp_executesql #cmd
end
select #cmd = 'insert into '+#sqltable+' ('+#fieldList+') exec sp_executesql N'+''''+#sqlcode+''''
exec sp_executesql #cmd
end try
begin catch
declare #m nvarchar(max)=object_name(##procid)+' error: '+error_message()+char(13)+'Line '+convert(nvarchar,ERROR_LINE())
raiserror(#m,1,1)
end catch end
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 want to find count of set of tables. The table names are values in another table.
--like
select count(*) from tablename
--tablename is obtained from
select tablename from table1
--table1 has around 171 tablenames
I was using cursor to get each table name and select count for each, but it is taking time. Can you please help how to replace cursor code with set based solution?
Below is my cursor code
SET NOCOUNT ON;
if( OBJECT_ID('tempdb..#temptablenew') IS NOT NULL )
BEGIN
DROP table #temptablenew
END
select * into #temptablenew from table1
declare #srccount int
declare #tablename nvarchar(max);
declare #q2 nvarchar(max);
declare #id int;
declare my_cursor cursor
local static read_only forward_only
for
select id,tablename from #temptablenew
open my_cursor
fetch next from my_cursor
into #id,#tablename
while ##fetch_status = 0
begin
set #q2 =N'select #srccount= count(*) from '+#tablename+' with (nolock)';
execute sp_executesql #q2,#PARAMS = N'#srccount INT OUTPUT',
#srccount = #srccount OUTPUT
select #srccount,#id,#tablename
fetch next from my_cursor
into #id,#tablename
end
close my_cursor;
deallocate my_cursor;
Thanks in advance
Try this,
SET NOCOUNT ON;
declare #q2 nvarchar(max) = '';
SELECT #q2 = #q2 + 'SELECT COUNT(*) AS cnt, ''' + tablename + ''' AS TableName FROM ' + tablename + ' (NOLOCK); '
FROM table1
--Print #q2
execute sp_executesql #q2
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