I need some assistance with my tsql , I have knowledge of sql but mainly just querying tables and im finding tsql and loops quite difficult to finish off.
I have hit a sticking point with my IF STATEMENT.
As you can see I have wrote the loop and attempted some debugging and the code is correct so far.
In the Else section
I need to check if it’s the first time through the loop using #firstloop and then copy all data , its mainly the loop that I’m having problems with and could do with help on getting a starting point.
I am using cursors but have been told it won’t affect performance because it’s not doing too much work and I would appreciate any help with the problem.I have also been told that some sections are Hard coded such as Production2 which should be #Source_Database_Name.
declare #Source_Database_Name varchar(255) = 'Production2';
declare #Destination_Database_Name varchar(255) = 'c365online_script1';
declare #Company_Id int = 1 --declare a companyid
CREATE TABLE #CompanyID (ID bigint)
INSERT INTO #CompanyID(ID)
VALUES('15')
--FIRST CURSOR LOOP THROUGH THIS TABLE
CREATE TABLE #TableList (
processorder int,
tablename NVARCHAR(100)
)
INSERT INTO #TableList (processorder, tablename )
VALUES
(1, 'tProperty');
DECLARE #firstLoop BIT
--SET #firstLoop = true
DECLARE #Counter INT -- counting variable
----------- Cursor specific code starts here ------------
-- company cursor
declare copyCompanyDataCursor CURSOR fast_forward FOR
SELECT ID from #CompanyID;
open copyCompanyDataCursor
fetch next from copyCompanyDataCursor into #Company_Id;
WHILE ##FETCH_STATUS = 0
BEGIN
declare #processorder int;
declare #tablename varchar(500);
-- table cursor
declare copyTableDataCursor CURSOR fast_forward FOR
SELECT processorder,tablename from #TableList order by processorder;
open copyTableDataCursor
fetch next from copyTableDataCursor into #processorder, #tablename;
while ##FETCH_STATUS = 0
BEGIN
SET IDENTITY_INSERT [c365online_script1].[dbo].[tCompany] ON
-- Does the table have a companyID column? if statement checking for company id
IF EXISTS(SELECT * FROM Production2.INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME='CompanyID' and TABLE_NAME=#tablename)
BEGIN
declare #debug varchar(max)
SET #debug = 'INSERT INTO ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + CAST(#Company_Id as varchar(10))
print #debug
--EXEC(#debug)
--EXEC('INSERT INTO ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id )
END
ELSE
-- if no check if this is the first time through company loop and copy all data- if #firstloop company exists look at information schema
BEGIN
Print 'No'
END
-- if yes then copy data based on companyID in cursor
--EXEC('INSERT INTO ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename )
-- company logic
SET IDENTITY_INSERT [c365online_script1].[dbo].[tCompany] OFF
FETCH NEXT FROM copyTableDataCursor into #processorder,#tablename;
END
close copyTableDataCursor;
Deallocate copyTableDataCursor;
Not sure why you are using the cursor. To answer your question of "checking if its the first time gone through loop" then below is the soullution for this.
Declare a variable above "while ##FETCH_STATUS = 0" Line.
somethign like "Firsttime = 0 "
Under IF , "Firsttime = 1 " Which means this is not first time.
In ELSE , check
---> if "Firsttime = 0 " Then it mean first time
---> if "Firsttime = 1 " Then it mean its not first time
Related
I get the below error message, I have debugged both identity inserts and they execute with no problems. Has anyone had trouble with this error before and does anyone know how to fix this?
Msg 8101, Level 16, State 1, Line 1
An explicit value for the identity column in table 'c365online_script1.dbo.tProperty' can only be specified when a column list is used and IDENTITY_INSERT is ON.
Code:
declare #Source_Database_Name varchar(255) = 'Production2';
declare #Destination_Database_Name varchar(255) = 'c365online_script1';
declare #Company_Id int = 1 --declare a companyid
CREATE TABLE #CompanyID (ID bigint)
INSERT INTO #CompanyID(ID)
VALUES('15')
-- Copy over company records from tCompanytable
--FIRST CURSOR LOOP THROUGH THIS TABLE
CREATE TABLE #TableList (
processorder int,
tablename NVARCHAR(100)
)
INSERT INTO #TableList (processorder, tablename )
VALUES
(1, 'tProperty');
DECLARE #Counter INT = 0 -- counting variable
----------- Cursor specific code starts here ------------
-- company cursor
declare copyCompanyDataCursor CURSOR fast_forward FOR
SELECT ID from #CompanyID;
open copyCompanyDataCursor
fetch next from copyCompanyDataCursor into #Company_Id;
WHILE ##FETCH_STATUS = 0
BEGIN
declare #processorder int;
declare #tablename varchar(500);
-- table cursor
declare copyTableDataCursor CURSOR fast_forward FOR
SELECT processorder,tablename from #TableList order by processorder;
open copyTableDataCursor
fetch next from copyTableDataCursor into #processorder, #tablename;
while ##FETCH_STATUS = 0
BEGIN
SET IDENTITY_INSERT [c365online_script1].[dbo].[tCompany] ON
-- Does the table have a companyID column? if statement checking for company id
IF EXISTS(SELECT * FROM Production2.INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME='CompanyID' and TABLE_NAME=#tablename)
BEGIN
if #Counter <= 0 -- make sure loop executes only once.
BEGIN
declare #debug varchar(max)
SET #debug = 'INSERT INTO ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + CAST(#Company_Id as varchar(10))
print #debug
set #Counter = 1
EXEC(#debug)
--EXEC('INSERT INTO ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id )
END
END
ELSE
BEGIN
Print 'No'
END
-- if yes then copy data based on companyID in cursor
-- if no check if this is the first time through company loop and copy all data
-- if #firstloop company exists look at information schema
--EXEC('INSERT INTO ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename )
-- company logic
SET IDENTITY_INSERT [c365online_script1].[dbo].[tCompany] OFF
FETCH NEXT FROM copyTableDataCursor into #processorder,#tablename;
END
close copyTableDataCursor;
Deallocate copyTableDataCursor;
--INSERT INTO c365online_script1.dbo.tCompany
--SELECT *
--FROM production2.tCompany
--WHERE ISNULL(CompanyID, 0) = 0 -- copy all data where id is equal to zero
--#Destination_Database_Name
--
--EXEC(INSERT + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id + ')')
--SET #firstLoop = false;
FETCH NEXT FROM copyCompanyDataCursor into #Company_Id;
END
CLOSE copyCompanyDataCursor;
DEALLOCATE copyCompanyDataCursor;
--Cleanup
DROP TABLE #CompanyID
DROP TABLE #TableList
Well, the error says it all:
An explicit value for the identity column in table 'c365online_script1.dbo.tProperty' can only be specified when a column list is used and IDENTITY_INSERT is ON.
So your INSERT statement MUST use a column list!
Use
INSERT INTO dbo.Table(col1, col2, ...., colN) VALUES(Val1, val2, ...., ValN)
and not just
INSERT INTO dbo.Table VALUES(Val1, val2, ...., ValN)
^^^^ no column list defined!!
then it'll work!
Using SQl how would I check a column of all the tables in #DestinationDatabase if they have a CompanyID using an if statement? within the while loop of the code below?.
I have been told cursors have performance issues but this is the route that somebody above me has chosen to take.
DECLARE #firstLoop BIT
SET #firstLoop = true
DECLARE #Counter INT -- counting variable
----------- Cursor specific code starts here ------------
-- company cursor
declare copyCompanyDataCursor CURSOR fast_forward FOR
SELECT ID from #CompanyIDs;
open copyCompanyDataCursor
fetch next from copyCompanyDataCursor into #Company_Id;
WHILE ##FETCH_STATUS = 0
BEGIN
declare #processorder int;
declare #tablename varchar(500);
-- table cursor
declare copyTableDataCursor CURSOR fast_forward FOR
SELECT processorder,tablename from #TableList4 order by processorder;
open copyTableDataCursor
fetch next from copyTableDataCursor into #processorder, #tablename;
while ##FETCH_STATUS = 0
BEGIN
SET IDENTITY_INSERT [c365online_script1.dbo.tCompany] OFF
-- Does the table have a companyID column? if statement checking for company id
-- if yes then copy data based on companyID in cursor
ELSE
IF #firstLoop > =1 THEN
-- if no check if this is the first time through company loop and copy all data
-- if #firstloop company exists look at information schema
-- insert into c365online_script1.dbo.tCompany(selec
EXEC('INSERT ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ')')
-- company logic
SET IDENTITY_INSERT [c365online_script1.dbo.tCompany] ON
FETCH NEXT FROM copyTableDataCursor into #processorder,#tablename;
END
close copyTableDataCursor;
Deallocate copyTableDataCursor;
--INSERT INTO c365online_script1.dbo.tCompany
--SELECT *
--FROM production2.tCompany
--WHERE ISNULL(CompanyID, 0) = 0 -- copy all data where id is equal to zero
--#Destination_Database_Name
--
--EXEC(INSERT + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id + ')'
SET #firstLoop = false;
FETCH NEXT FROM copyCompanyDataCursor into #Company_Id;
END
CLOSE copyCompanyDataCursor;
DEALLOCATE copyCompanyDataCursor;
You can add this in your WHILE loop. I think this is the solution you're looking for.
IF (
SELECT 1
FROM sys.tables st
INNER JOIN sys.columns sc
ON st.object_id = sc.object_id
WHERE st.NAME = #tablename
AND sc.NAME = #company_id
) > 0
BEGIN
-- your logic here --
END
ELSE
-- other logic here --
I am creating an sql script , I have 2 cursors to loop through data a table cursor and a company cursor .
I am having issues putting the company cursor together using while loops to copy data into the schema
I need to answer the below questions using an If Statement
Does the table have a companyID column? an if statement checking for company id
if yes then copy data based on companyID in cursor
I have a #firstLoop declared
Here is my cursor specific code
DECLARE #firstLoop BIT
SET #firstLoop = true
----------- Cursor specific code starts here ------------
-- company cursor
declare copyCompanyDataCursor CURSOR fast_forward FOR
SELECT ID from #CompanyIDs;
open copyCompanyDataCursor
fetch next from copyCompanyDataCursor into #Company_Id;
WHILE ##FETCH_STATUS = 0
BEGIN
declare #processorder int;
declare #tablename varchar(500);
-- table cursor
declare copyTableDataCursor CURSOR fast_forward FOR
SELECT processorder,tablename from #TableList4 order by processorder;
open copyTableDataCursor
fetch next from copyTableDataCursor into #processorder, #tablename;
while ##FETCH_STATUS = 0
BEGIN
SET IDENTITY_INSERT [c365online_script1.dbo.tCompany] OFF
-- Does the table have a companyID column? if statement checking for company id
-- if yes then copy data based on companyID in cursor
-- if no check if this is the first time through company loop and copy all data
-- if #firstloop company exists look at information schema
-- insert into c365online_script1.dbo.tCompany(selec
EXEC('INSERT ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ')')
-- company logic
SET IDENTITY_INSERT [c365online_script1.dbo.tCompany] ON
FETCH NEXT FROM copyTableDataCursor into #processorder,#tablename;
END
close copyTableDataCursor;
Deallocate copyTableDataCursor;
--INSERT INTO c365online_script1.dbo.tCompany
--SELECT *
--FROM production2.tCompany
--WHERE ISNULL(CompanyID, 0) = 0 -- copy all data where id is equal to zero
--#Destination_Database_Name
--
--EXEC(INSERT + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id + ')'
SET #firstLoop = false;
FETCH NEXT FROM copyCompanyDataCursor into #Company_Id;
END
CLOSE copyCompanyDataCursor;
DEALLOCATE copyCompanyDataCursor;
I suggest you replace both the CURSORS with while loop.
CURSORS in SQL Server cost performance very badly instead replacing them with temporary table with While loop will certainly boost the performance and an easier type of coding you will have to write.
For articles about SQL Server please check the below link
SQL Server real time articles
Every time I run the query I get the syntax error. The thing is when I run the lines where the error is supposedly occurring the code runs that section so I don't know why I'm getting the below error messages.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ')'.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ')'.
My code:
declare #Source_Database_Name AS varchar(255) = 'dbo.Production2';
declare #Destination_Database_Name AS varchar(255) = 'c365online_script1';
declare #Company_Id int = 1 --declare a companyid
CREATE TABLE #CompanyID1 (ID bigint)
INSERT INTO #CompanyID1(ID)
VALUES('1')
--FIRST CURSOR LOOP THROUGH THIS TABLE
CREATE TABLE #TableList (
processorder int,
tablename NVARCHAR(100)
)
INSERT INTO #TableList (processorder, tablename )
VALUES
(1, 'tCompany');
DECLARE #firstLoop BIT
--SET #firstLoop = true
DECLARE #Counter INT -- counting variable
----------- Cursor specific code starts here ------------
-- company cursor
declare copyCompanyDataCursor CURSOR fast_forward FOR
SELECT ID from #CompanyID1;
open copyCompanyDataCursor
fetch next from copyCompanyDataCursor into #Company_Id;
WHILE ##FETCH_STATUS = 0
BEGIN
declare #processorder int;
declare #tablename varchar(500);
-- table cursor
declare copyTableDataCursor CURSOR fast_forward FOR
SELECT processorder,tablename from #TableList order by processorder;
open copyTableDataCursor
fetch next from copyTableDataCursor into #processorder, #tablename;
WHILE ##FETCH_STATUS = 0
BEGIN
SET IDENTITY_INSERT [c365online_script1].[dbo].[tCompany] ON
-- Does the table have a companyID column? if statement checking for company id
IF EXISTS(SELECT * FROM Production2.INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME='CompanyID' and TABLE_NAME='tProperty')
BEGIN
declare #debug varchar(max)
EXEC('INSERT' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id + ')')
END
ELSE
BEGIN
Print 'No'
END
-- if yes then copy data based on companyID in cursor
-- if no check if this is the first time through company loop and copy all data
-- if #firstloop company exists look at information schema
-- insert into c365online_script1.dbo.tCompany(selec
EXEC('INSERT ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ')')
-- company logic
SET IDENTITY_INSERT [c365online_script1].[dbo].[tCompany] OFF
FETCH NEXT FROM copyTableDataCursor into #processorder,#tablename;
END
close copyTableDataCursor;
Deallocate copyTableDataCursor;
--INSERT INTO c365online_script1.dbo.tCompany
--SELECT *
--FROM production2.tCompany
--WHERE ISNULL(CompanyID, 0) = 0 -- copy all data where id is equal to zero
--#Destination_Database_Name
--
--EXEC(INSERT + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id + ')')
--SET #firstLoop = false;
FETCH NEXT FROM copyCompanyDataCursor into #Company_Id;
END
CLOSE copyCompanyDataCursor;
DEALLOCATE copyCompanyDataCursor;
Looks like extra brackets at the end of each of these lines:
EXEC('INSERT' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id + ')')
EXEC('INSERT ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ')')
There is a closing bracket in quotes, but no opening bracket to correspond to it.
I have the below cursor. It generates the right set of statements but I am not able to insert the data into the temporary created table. The cursor is as below. Please have a look.
--use a cursor to get the stats
use qcsiteadmin_db0
-- Declare the variables needed
DECLARE #DOMAIN_NAME VARCHAR(255)
DECLARE #PROJECT_NAME VARCHAR(255)
DECLARE #DB_NAME VARCHAR(60)
DECLARE #SQL NVARCHAR(max)
DECLARE #COUNTSQL NVARCHAR(2000)
DECLARE #FOLDER VARCHAR(255)
---DECLARE #FILTER VARCHAR(500)
select #FOLDER = 'System Validation'
-- Create a Temp Table
CREATE TABLE #defects(
DOMAIN_NAME VARCHAR(255),
PROJECT_NAME varchar(255),
DEFECT_NUMBER int,
SUMMARY VARCHAR(255),
ASSIGNED_TO VARCHAR(255),
DESCRIPTION VARCHAR(8000),
STATUS VARCHAR(255),
PRIORITY int)
--Declare the Cursor for looping the database calls
DECLARE qc_dbs CURSOR FOR
select DOMAIN_NAME,PROJECT_NAME,DB_NAME
from td.PROJECTS
where PR_IS_ACTIVE = 'Y'
and DOMAIN_NAME not in
('mk_conversion', 'default','other','z_archivedprojects','sqa')
order by DOMAIN_NAME,PROJECT_NAME
--For each valid QC database get the defect counts needed
OPEN qc_dbs
FETCH NEXT FROM qc_dbs INTO #DOMAIN_NAME,#PROJECT_NAME,#DB_NAME
WHILE ##FETCH_STATUS = 0
BEGIN
select #SQL = 'select ''' + #DOMAIN_NAME + ''', ''' + #PROJECT_NAME + ''', ' + #DB_NAME + '.td.bug.BG_BUG_ID, ' + #DB_NAME + '.td.bug.BG_SUMMARY, ' + #DB_NAME + '.td.bug.BG_RESPONSIBLE,
' + #DB_NAME + '.td.bug.BG_PRIORITY
from ' + #DB_NAME + '.td.CYCL_FOLD ' +
' INNER JOIN ' + #DB_NAME + '.td.bug on '
+ #DB_NAME + '.td.CYCL_FOLD.CF_ASSIGN_RCYC = ' + #DB_NAME + '.td.BUG.BG_DETECTED_IN_RCYC
and ' + #DB_NAME + '.td.CYCL_FOLD.CF_ITEM_NAME = ''' + #FOLDER + ''' and ' + #DB_NAME + '.td.BUG.BG_STATUS = ''New'' '
print #SQL
BEGIN TRY
insert into #defects
execute (#SQL)
END TRY
BEGIN CATCH
print 'Error accessing' + #DOMAIN_NAME + '.' + #PROJECT_NAME
END CATCH;
FETCH NEXT FROM qc_dbs INTO #DOMAIN_NAME,#PROJECT_NAME,#DB_NAME
END
-- Close the Cursor
CLOSE qc_dbs
DEALLOCATE qc_dbs
--Select from Temp Table
select
DOMAIN_NAME,PROJECT_NAME,
DEFECT_NUMBER,SUMMARY,ASSIGNED_TO,DESCRIPTION,
STATUS, PRIORITY
from #defects
-- Destroy the Temp Table
Drop TABLE #defects
My output messsages look like -
select 'ADMIN_SYSTEMS', '1099Process', admin_systems_1099process_db.td.bug.BG_BUG_ID, admin_systems_1099process_db.td.bug.BG_SUMMARY, admin_systems_1099process_db.td.bug.BG_RESPONSIBLE,
admin_systems_1099process_db.td.bug.BG_PRIORITY
from admin_systems_1099process_db.td.CYCL_FOLD INNER JOIN admin_systems_1099process_db.td.bug on admin_systems_1099process_db.td.CYCL_FOLD.CF_ASSIGN_RCYC = admin_systems_1099process_db.td.BUG.BG_DETECTED_IN_RCYC
and admin_systems_1099process_db.td.CYCL_FOLD.CF_ITEM_NAME = 'System Validation' and admin_systems_1099process_db.td.BUG.BG_STATUS = 'New'
(0 row(s) affected)
Error accessingADMIN_SYSTEMS.1099Process
Please have a look.
Regards.