Create Northwind.mdf for use in local db - sql-server

The following is the start if the standard Install Northwind sql script as provided by Microsoft in their Install sql server 200 sample databases.
SET NOCOUNT ON
GO
USE master
GO
if exists (select * from sysdatabases where name='Northwind')
drop database Northwind
go
DECLARE #device_directory NVARCHAR(520)
SELECT #device_directory = SUBSTRING(filename, 1, CHARINDEX(N'master.mdf', LOWER(filename)) - 1)
FROM master.dbo.sysaltfiles WHERE dbid = 1 AND fileid = 1
EXECUTE (N'CREATE DATABASE Northwind
ON PRIMARY (NAME = N''Northwind'', FILENAME = N''' + #device_directory + N'northwnd.mdf'')
LOG ON (NAME = N''Northwind_log'', FILENAME = N''' + #device_directory + N'northwnd.ldf'')')
go
exec sp_dboption 'Northwind','trunc. log on chkpt.','true'
exec sp_dboption 'Northwind','select into/bulkcopy','true'
GO
set quoted_identifier on
GO
Under normal circumstances I always use a full copy of sql server or sql server express for development, however an unrelated support issue with a third party component has occurred that requires me to provide a self contained sample application with the basic nortwind database file contained within the sample using localdb.
To that end how should I adapt the Execute Create Database section of the sql script so that it will create a copy of the nortwind .mdf in a given location (let's say C:\MyData so that I can then use, that file to send with the sample I need to build for the support team. Essentially it is vital that they have a completely self contained sample to help narrow down the problem.
Many Thanks

Related

How can I disable autogrowth in SQL Server wide

I have a database server that some databases with restricted users are in use in the database. I need to restrict users to can't change .MDF and .LDF autogrowth settings. Please guide me to restrict the users.
I think there is two way to get this access:
Disable autogrowth in databases
Limit the maximum size of MDF and LDF
But I couldn't find any option in Management Studio to do them server wide and also get access from users.
Thanks.
you can execute following ALTER DATABASE command which sets auto growth option to off for all databases using undocumented stored procedure sp_Msforeachdb
for single database (Parallel Data Warehouse instances only)
ALTER DATABASE [database_name] SET AUTOGROW = OFF
for all databases
EXEC sp_Msforeachdb "ALTER DATABASE [?] SET AUTOGROW = OFF"
Although this is not a server variable or instance settings, it might help you ease your task for updating all databases on the SQL Server instance
By excluding system databases and for all other databases, following T-SQL can be executed to get list of all database files and output commands prepared can be executed
select
'ALTER DATABASE [' + db_name(database_id) + '] MODIFY FILE ( NAME = N''' + name + ''', FILEGROWTH = 0)'
from sys.master_files
where database_id > 4
To prevent data files' autogrow property to be changed, I prepared below SQL Server DDL trigger once I used a DDL trigger for logging DROP table statements.
Following trigger will also prevent you to change this property, so if you need to update this property, you have to drop this trigger first.
CREATE TRIGGER prevent_filegrowth
ON ALL SERVER
FOR ALTER_DATABASE
AS
declare #SqlCommand nvarchar(max)
set #SqlCommand = ( SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)') );
if( isnull(charindex('FILEGROWTH', #SqlCommand), 0) > 0 )
begin
RAISERROR ('FILEGROWTH property cannot be altered', 16, 1)
ROLLBACK
end
GO
For more on DDL Triggers, please refer to Microsoft Docs

How to set change tracking on a Visual Studio database project (SSDT)

I have a SQL Server 2005 DB project and am looking to deploy the Schema over an existing DB that is on a later version of SQL Server. The issue I have is that Change Tracking is enabled on the DB I wish to deploy to and so the first thing SSDT wants to do is disable CT. This poses a problem as I get the error below:
(43,1): SQL72014: .Net SqlClient Data Provider: Msg 22115, Level 16,
State 1, Line 5 Change tracking is enabled for one or more tables in
database 'Test'. Disable change tracking on each table before
disabling it for the database. Use the sys.change_tracking_tables
catalog view to obtain a list of tables for which change tracking is
enabled. (39,0): SQL72045: Script execution error. The executed
script:
IF EXISTS (SELECT 1
FROM [master].[dbo].[sysdatabases]
WHERE [name] = N'$(DatabaseName)')
BEGIN
ALTER DATABASE [$(DatabaseName)]
SET CHANGE_TRACKING = OFF
WITH ROLLBACK IMMEDIATE;
END
In an effort to get around this I have created a PreDeployment script that executes the below:
/* Run pre-deployment scripts to resolve issues */
IF(SELECT SUBSTRING(##VERSION, 29,4)) = '11.0'
BEGIN
PRINT 'Enabling Change Tracking';
DECLARE #dbname VARCHAR(250)
SELECT #dbname = DB_NAME()
EXEC('
IF NOT EXISTS(SELECT * FROM [master].[dbo].[sysdatabases] WHERE name = ''' + #dbname + ''')
ALTER DATABASE ['+ #dbname +
']SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 5 DAYS, AUTO_CLEANUP = ON);
');
EXEC('
IF NOT EXISTS(SELECT * FROM sys.change_tracking_tables ctt
INNER JOIN sys.tables t ON t.object_id = ctt.object_id
INNER JOIN sys.schemas s ON s.schema_id = t.schema_id
WHERE t.name = ''TableName'')
BEGIN
ALTER TABLE [dbo].[TableName] ENABLE CHANGE_TRACKING;
END;');
So based on the DB Version Change Tracking is set to enabled on the DB and relevant Tables assuming it is not already enabled.I got this idea from a previous post: # ifdef type conditional compilation in T-SQL sql server 2008 2005
Unfortunately this is still not working as SSDT is trying to disable Change Tracking before the PreDeployment script is executed.
Make sure change tracking is enabled in your database project.
Open your database project's properties > Project Settings > Database Settings... > Operational tab > check the "Change tracking" option
As Keith said if you want it in enable it. If you do want to disable it then just run your script before doing the compare so you have a pre-pre-deploy script like:
https://the.agilesql.club/Blog/Ed-Elliott/Pre-Compare-and-Pre-Deploy-Scripts-In-SSDT
If you are disabling it then it is a one off thing so pretty simple.
Other options are to write your own deployment contributor and raising a bug via connect.
Deployment Contributor:
https://the.agilesql.club/blog/Ed-Elliott/2015/09/23/Inside-A-SSDT-Deployment-Contributor
https://github.com/DacFxDeploymentContributors/Contributors
Ed

Is there a way to query SQL Server linked server without hardcoding database name?

I found samples where the code:
SELECT * FROM [legacyserver].[database].[schema].[table]
was expressed as:
SELECT * FROM [legacyserver]...[table]
but isn't working for me.
It gives me the error:
An invalid schema or catalog was specified for the provider "MSDASQL" for linked server "legacyserver".
I'm using for legacy server SQL SERVER 2000 and for the new server SQL SERVER 2012.
I tried creating the linked server using:
EXEC sp_addlinkedserver
#server = 'legacyserver',
#srvproduct = '',
#provider = 'MSDASQL',
#provstr = 'DRIVER={SQL Server};SERVER=legacyserver;DATABASE=database;Trusted_Connection=Yes;',
and:
EXEC sp_addlinkedserver
#server = 'legacyserver',
#srvproduct = '',
#provider = 'MSDASQL',
#provstr = 'DRIVER={SQL Server};SERVER=legacyserver;Trusted_Connection=Yes;',
#catalog = 'database';
Is it possible to create the script without hard coding the database name?
I need to create a really big migration script and it need to use a development, acceptance and production databases, and it will be to much work and error prone to change it using replace in the text editor.
UPDATE:
The legacy development, acceptance and production databases are exactly the same (except for the data) and each one have it's own server/instance and database name.
Due to segregation of duties, I can't develop something and deploy it, so I have no way to touch this script after acceptance. I will need to instruct someone else to do so, and if he/she will need to replace every occurrence of [legacyserver].[database], the chances of mistakes are very high.
You can create a synonym
CREATE SYNONYM [table] FOR [legacyserver].[database].[schema].[table]
When you query
SELECT * FROM table
it's actually fetching data from linked server instead of local database.
If want to change database, just drop synonym and create a new one with new database name.
DROP SYNONYM table;
CREATE SYNONYM [table] FOR [legacyserver].[anotherdatabase].[schema].[table]
Your query statement is unchanged.
EDIT: DROP and CREATE SYNONYM statement is a little misleading. You don't need to do it yourself. It's one time job in deployment. Just create a Post-Deployment script that creates all synonyms and parametrize linked server name and database names. Code like:
IF EXISTS (SELECT * FROM sys.synonyms WHERE name = 'table1')
BEGIN
DROP SYNONYM table1
END
EXEC('CREATE SYNONYM table1 FOR ' + '$(LinkedServerName).$(DBName).[dbo].[Table1]')
Note, it use SQLCMD syntax.
Ask operations to change parameter in different environments.

How can I create backup script from diagram in SQL Server?

I use SQL Server 2012 and SQL Server 2008 R2.
I create a script from all object (tables / trigger / stored procedure / function ...) in my database.
I generated this script from SQL Server Management Studio. I can recreate my database with this scrips on the other server. But I miss all diagrams of my database after run my script for create another database.
Therefore, I need create backup script from all diagrams that exist in my database.
I need execute this script on the destination database for recreating all my diagrams.
I found this Link. but i need some thinks that create all script (Insert Command) automatically.
I have found a reasonable solution. The problem is that Management Studio cannot display more that 65535 characters for Non-XML data, and cannot be set to display more than 65535.
See code for documentation :)
Backup script:
-- 1. Read from DB, using XML to workaround the 65535 character limit
declare #definition varbinary(max)
select #definition = definition from dbo.sysdiagrams where name = 'ReportingDBDiagram'
select
'0x' + cast('' as xml).value('xs:hexBinary(sql:variable("#definition") )', 'varchar(max)')
for xml path('')
-- 2. Open the result XML in Management Studio
-- 3. Copy the result
-- 4. Paste this in backup script for #definition variable
Restore script:
declare #definition varbinary(max)
set #definition = 0xD0CF -- Paste 0x0 value from Backup script
-- Create diagram using 'official' Stored Procedure
exec dbo.sp_creatediagram
#diagramname = 'ReportingDBDiagramCopy',
#owner_id = null,
#version = 1,
#definition = #definition
Scripting your database does not include diagrams as they are not server objects in the same way as a table or stored procedure; they exist as data in the sysdiagrams table.
A similar question on SO asked How do you migrate SQL Server Database Diagrams to another Database?
The accepted answer is to copy the contents of the sysdiagrams table to the new database, so you could include the table contents in your script. The answer with the most up-votes has a link to a way of scripting diagrams.
I've tried backing up and then restoring a database to the same server, deleting the diagram I had created (I only had one) and then running the following query:
INSERT INTO database2.dbo.sysdiagrams
(
NAME
,principal_id
,version
,DEFINITION
)
SELECT NAME
,principal_id
,version
,DEFINITION
FROM database1.dbo.sysdiagrams
The diagram was successfully restored, however I did do this on a restored backup, I should really test it with a new database generated from a script.
UPDATE:
I scripted a database and then created a new database from it. When trying to rebuild the diagrams using an INSERT statement I got the error
So although it seems possible it's not trivial to create diagrams in a new database created from a script. Go with the answer given regarding scripting diagrams and modify it for your own needs.
Perhaps you can investigate further and post your own answer :)
Here's a quick & dirty method I use. Since the query window won't display the full varbinary(max) value of the definition field, but the XML editor will, I output the rows to XML as follows:
Run the following query on the server/database that contains the diagrams:
SELECT 'INSERT sysdiagrams(name,principal_id,diagram_id,version,definition) VALUES('''+name+''','
+CONVERT(varchar(2),principal_id)+','+CONVERT(varchar(2),diagram_id)+','+CONVERT(varchar(2),version)+','
+'0x' + CAST('' as xml).value('xs:hexBinary(sql:column("definition"))','varchar(max)') +')'
FROM RCSQL_ClaimStatus.dbo.sysdiagrams
FOR XML PATH
Click on the generated link to open the XML result, and ctrl-a & ctrl-c to copy all rows generated.
Paste that output back into your query window. I usually paste it between a pair of IDENTITY_INSERT's like this:
--TRUNCATE TABLE sysdiagrams
SET IDENTITY_INSERT sysdiagrams ON;
<row>INSERT sysdiagrams(name,principal_id,diagram_id,version,definition) VALUES('ERD1',1,1,1,0xD0CF11E0A1B11AE100000...)</row>
<row>INSERT sysdiagrams(name,principal_id,diagram_id,version,definition) VALUES('ERD2',1,2,1,0xD0CF11E0A1B11AE100000...)</row>
<row>INSERT sysdiagrams(name,principal_id,diagram_id,version,definition) VALUES('ERD3',1,3,1,0xD0CF11E0A1B11AE100000...)</row>
SET IDENTITY_INSERT sysdiagrams OFF;
Remove the row & /row XML tags from your inserts, and run them on the target server. You can truncate the sysdiagrams table if you're replacing all values with new values.

How can I copy an entire database to another on the same server?

I want to copy a database A into database B (same SQL Server) entirely - what would be the easiest SQL or utility command to do that? (database B should be 100% erased before the copy)
Note that it can be non-SQL thing, but in any case I need to run it as one-click. So some utility that does that is also acceptable as far as I can run copying with one click or from command line.
SQL Server 2008R2 or 2012.
Best, Askar
I made a soultion based on David's thoughts. It looks like this (Prod - source DB, Demo - destination copy)
DECLARE #backup varchar(300) = 'e:\Prod.bak';
DECLARE #logic_db_file varchar(300) = 'koe';
DECLARE #logic_log_file varchar(300) = 'koe_log';
DECLARE #out_db_file varchar(300) = 'c:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\Demo.mdf';
DECLARE #out_log_file varchar(300) = 'c:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\Demo_log.ldf';
PRINT N'Backing up Production database.'
BACKUP DATABASE Prod
TO DISK = #backup WITH FORMAT;
PRINT N'Restoring FILELISTONLY, see log file for data.'
-- Restore the files to Demo
RESTORE FILELISTONLY
FROM DISK = #backup
PRINT N'Getting exclusive access to Demo'
Alter database Demo set single_user with rollback immediate
drop database Demo
PRINT N'Restoring backup to Test database'
RESTORE DATABASE Demo
FROM DISK = #backup
WITH REPLACE,
MOVE #logic_db_file TO #out_db_file,
MOVE #logic_log_file TO #out_log_file
GO
-- if you want you can do some SQL fixes to newly made DB
PRINT N'Changing normal users to demo users, if account type is OK'
USE Demo;
UPDATE USER_ACCOUNTS SET ACCOUNT_TYPE=3 WHERE (STATUS=1) AND (ACCOUNT_TYPE=1);
GO

Resources