Write script to Migrate data from one database to another in SQL - sql-server

I want to migrate data from one database to another. I have written my sql statements to do so. However, the issue I a, facing is, I need to "use databasename GO" before executing the query (Can I fire use B and A at the same time to run my script?). Below is my query.
Use B GO
Use A GO
IF NOT EXISTS (select 1 FROM B.INFORMATION_SCHEMA.TABLES where table_schema = 'dbo' and table_name = 'Animal')
BEGIN
PRINT 'Table does not exist'
RETURN
END
GO
IF NOT EXISTS (select 1 FROM B.INFORMATION_SCHEMA.TABLES where table_schema = 'dbo' and table_name = 'Animal')
BEGIN
PRINT 'Table does not exist'
RETURN
END
GO
SET IDENTITY_INSERT B.[dbo].Animal ON GO
INSERT INTO B.[dbo].Animal
(Id, Name)
SELECT (Id, Name)
From A.dbo.Animal
GO
SET IDENTITY_INSERT B.[dbo].Animal OFF
GO
Would this work to move the data?

Related

Method to bulk modify triggers in SQL Server database

I have a database that uses Insert, Update, and Delete Triggers for almost all tables. They log the host and program performing the operation in a separate auditing table. The triggers all include this select statement to set variables that get inserted into the auditing table:
select #HostName = HostName, #ProgramName = Program_Name
from master..sysprocesses where SPID = ##SPID
We are now looking to migrate to Azure SQL Database, which does not support the master..sysprocesses syntax. It also appears that table is deprecated as well: https://learn.microsoft.com/en-us/sql/relational-databases/system-compatibility-views/sys-sysprocesses-transact-sql?view=sql-server-ver15
What we need to do is update the triggers to use this instead:
select #HostName = [host_name], #ProgramName = [program_name]
from sys.dm_exec_sessions where session_id = ##SPID
However, the database has hundreds of tables and each table has three triggers that need updating. The text-replacement for each trigger is identical. Is there a feasible way to script out something to perform this update on all triggers in the database?
OK, I just tested this by jamming your string in a few triggers (as a comment of course) and then running it. I am not advocating this as the correct way to do it, as this link will help you with the correct way to do dynamic sql https://dba.stackexchange.com/questions/165149/exec-vs-sp-executesql-performance
However, this does work and will help you understand how you would piece these things together to get to that point.
Note, any formatting difference between your triggers may cause this to miss some, so youll want to verify that 0on your own.
DECLARE #string VARCHAR(8000)='select #HostName = HostName, #ProgramName = Program_Name
from master..sysprocesses where SPID = ##SPID'
, #counter INT=1
, #Max INT
, #Sql VARCHAR(mAX)
;
IF OBJECT_ID('TempDB..#TrigUpdate') IS NOT NULL DROP TABLE #TrigUpdate;
CREATE TABLE #TrigUpdate
(
SqlVar VARCHAR(MAX)
, RowID INT
)
;
INSERT INTO #TrigUpdate
SELECT REPLACE(REPLACE(t.definition, #string, ''), 'CREATE TRIGGER', 'ALTER TRIGGER')
, Row_Number() OVER (ORDER BY t.Definition ASC) AS RowID
FROM sys.objects o
INNER JOIN sys.sql_modules t on o.object_id =t.object_id
WHERE o.type_desc='SQL_TRIGGER'
AND CHARINDEX(#string, t.definition,1)>0
;
SET #Max = (SELECT COUNT(*) FROM #TrigUpdate);
WHILE #Counter<=#Max
BEGIN
SET #sql = (SELECT SqlVar FROM #TrigUpdate WHERE RowID=#counter);
EXEC(#Sql);
SET #Counter=#Counter+1;
END
It could be done with Object_Definition and Replace.
Create Table #Triggers_new (TriggerName sysname, QueryText VarChar(max))
Declare #string_pattern VarChar(max), #string_replacement VarChar(max)
Select #string_pattern = '<string_pattern>'
Select #string_replacement = '<string_replacement>'
Insert Into #Triggers_new (TriggerName, QueryText)
Select [name], Replace(Object_Definition(object_id), #string_pattern, #string_replacement)
From sys.objects
Where [type] = 'TR'
Order by [name]
-- Update #Triggers_new Set QueryText = Replace(QueryText, 'Create Trigger ', 'Alter Trigger ')
Why do you use a so heavy query on system table/view that can be changed without your consent ?
Can't you simplify you by using metada functions like :
SELECT HOST_NAME(), PROGRAM_NAME()...
That will give the requested information values ?

Insert Data over a linked server or different database

I would like to know what would be a safe way to insert data over a linked/local server into a empty copy of the database(This database will have the same table structure) using "INSERT INTO SELECT"?
I will be getting data from the local server and this data will be inserted over a linked server or local server to an archive DB.
This process needs to happen through Dynamic SQL as I am writing a Generic script.
If you have a sample script that you can supply to me then I would appreciate it.
EXAMPLE
EXEC [server_name].[OI_OAF_Archive_20210218_20210222].[dbo].sp_executesql N'SET IDENTITY_INSERT [OI_OAF_Archive_20210218_20210222].dbo.[ENT_Entry] ON'
EXEC [server_name].[OI_OAF_Archive_20210218_20210222].[dbo].sp_executesql N'ALTER TABLE [OI_OAF_Archive_20210218_20210222].dbo.[ENT_Entry] NOCHECK CONSTRAINT ALL'
IF (EXISTS (SELECT * FROM [OI_OAF_Archive_20210218_20210222].INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'ENT_Entry'))
BEGIN
PRINT 'Inserting into the table ENT_Entry'
INSERT INTO [server_name].[OI_OAF_Archive_20210218_20210222].dbo.[ENT_Entry] (entryID,details,createdByID,createdDate,lastModifiedByID,lastModifiedDate,localityID,refNumber,entryDate,gps,reloadEscStep,createdAt,reloadOccurrenceChecklistRule) SELECT entryID,details,createdByID,createdDate,lastModifiedByID,lastModifiedDate,localityID,refNumber,entryDate,gps,reloadEscStep,createdAt,reloadOccurrenceChecklistRule FROM OPENQUERY([server_name], 'SELECT entryID,details,createdByID,createdDate,lastModifiedByID,lastModifiedDate,localityID,refNumber,entryDate,gps,reloadEscStep,createdAt,reloadOccurrenceChecklistRule FROM TMP_Archive_ENT_Entry_70CDC91A ');
END
EXEC [server_name].[OI_OAF_Archive_20210218_20210222].[dbo].sp_executesql N'SET IDENTITY_INSERT [OI_OAF_Archive_20210218_20210222].dbo.[ENT_Entry] OFF'
EXEC [server_name].[OI_OAF_Archive_20210218_20210222].[dbo].sp_executesql N'ALTER TABLE [OI_OAF_Archive_20210218_20210222].dbo.[ENT_Entry] CHECK CONSTRAINT ALL'
This Example is where I INSERT the DATA from The archive server, but I want to insert it from the local server into the archive server, would that be possible?

How to Submit a T-SQL script

I'm new to SQL Server and was trying some SQL statements for my database.
I want to enable identity insert with the following statement:
SET IDENTITY_INSERT tableName ON
That works fine. After that I inserted an entry but if I close the script the changes are lost.
I also tried
EXEC sp_MSforeachtable #command1="PRINT '?'; SET IDENTITY_INSERT ? ON",
#whereand = ' AND EXISTS (SELECT 1 FROM sys.columns WHERE object_id = o.id AND is_identity = 1) and o.type = ''U'''
to enable identity insert for all tables, but that did not work either.
My expectation was that I run that script once and it will change the DB for all time but if I try to insert some entries with identity column, it doesn't insert the entry.

Convert SQL Server trigger to Oracle and master.dbo.sysprocesses - not duplicate

I tried searching but could not find exactly what I'm looking for. I'm new to SQl Server and involved into SQL Server to Oracle conversion, and it is manual conversion. All I have is SQL Server files.
I see two types of SQL Server triggers - FOR UPDATE and FOR INSERT. They look to me as before update and before insert triggers in Oracle. I'd like to confirm this please and if you can provide examples that would be great.
Also, what is the equivalent to master.dbo.sysprocesses in Oracle please? Is this v$session? I can get user from dual in Oracle. Is this what nt_username is in below code?
Here is typical code examples I need to convert to Oracle - is this before insert?
CREATE TRIGGER trigger_name ON dbo.table_name
FOR Insert AS
declare #InsertUser varchar(32)
BEGIN
SELECT #InsertUser = nt_username from master.dbo.sysprocesses where spid = ##spid
Update table_name
SET dCreateDate = GETDATE(), cCreateUser = #InsertUser
FROM table1 a ,table2 i WHERE a.tab_id = i.tab_id
END
GO
Update Trigger - before update?
CREATE TRIGGER trigger_name ON dbo.table_name
FOR UPDATE AS
declare #UpdateUser varchar(32)
if not update(CreateUser) and not update(CreateDate)
BEGIN
SELECT #UpdateUser = nt_username from master.dbo.sysprocesses where spid = ##spid
Update table_name
SET UpdateDate = GETDATE(), UpdateUser = #UpdateUser
FROM table1 a ,table2 i WHERE a.tab_id = i.tab_id
END
GO
Should I combine these two into if inserting... elsif updating in Oracle?
Thank you very much to all.

SQL script runs fine on one database, errors on another

We have a script that must allow for being re-run several times.
We have an MS-SQL script that updates a table if a (now obsolete) column exists, then deletes the column. To ensure that the script can be run several times, it first checks for the existence of a column before performing the updates.
The script works as expected on our dev database, updating the data on the first run, then displaying the message 'Not updating' on subsequent runs.
On our test database the script runs fine on the first run, but errors with "Invalid column name 'OldColumn'" on subsequent runs; if I comment out the UPDATE and ALTER statements it runs as expected.
Is there a way to force the script to run even if there's a potential error, or is it something to do with how the database was set-up? (fingers crossed I'm not looking like a complete noob!)
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'MyTable' AND COLUMN_NAME = 'OldColumn')
BEGIN
PRINT 'Updating and removing old column...'
UPDATE MyTable SET NewColumn='X' WHERE OldColumn=1;
ALTER TABLE MyTable DROP COLUMN OldColumn;
END
ELSE
PRINT 'Not updating'
GO
As a work around you could do
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'MyTable' AND COLUMN_NAME = 'OldColumn')
BEGIN
PRINT 'Updating and removing old column...'
EXEC ('UPDATE MyTable SET NewColumn=''X'' WHERE OldColumn=1;');
ALTER TABLE MyTable DROP COLUMN OldColumn;
END
ELSE
PRINT 'Not updating'

Resources