I have Two Database some-db-dev & some-db-qa. Both the databases are identical to each other.
I have created a DACPAC File for both the databases. some-db-dev.dacpac and some-db-qa.dacpac respectively.(It had the Table as "A" and Column "Test" in it. It also had some dummy records in it.)
After this I have performed below steps:
Renamed the Table "A" to "ARenamed" from some-db-dev Database.
Generated the DACPAC of "some-db-dev" and Stored it with the name "some-db-dev"
I have fire below command :-
sqlpackage /a:Script /sf:"C:\Users\some.user\Desktop\some-db-dev.dacpac" /tf:"C:\Users\some.user\Desktop\some-db-qa.dacpac" /tdn:"some-db-qa" /op:"C:\Users\some.user\Desktop\diffscript.sql"
Observations :-
Instead of renaming the Table modified at Step 1. It generated the Script of creating the table as below.
`GO
PRINT N'Creating [dbo].[ARenamed]...';
GO
CREATE TABLE [dbo].[ARenamed] (
[Id] NCHAR (10) NULL,
[Name] NCHAR (10) NULL,
[Test] NCHAR (10) NULL
);`
Is there something wrong with the command that I am using ??
Any help will be appreciable.
To rename a table in SSDT you need to use the refactoring tools "right click on the table and do refactor-rename". What happens is this adds an entry to the "RefactorLog.xml" - if you have one of those then when a deployment is created an sp_rename is generated, other you will get what you see here a drop and then create.
See: https://the.agilesql.club/2016/09/refactoring-in-sql-server-data-tools-ssdt/
The last section "Renaming Objects" shows how to do it.
Ed
I think that you'll need to use MSBuild instead. That's an example how to generate script project vs database.
MsBuild.exe "PATH_TO_SQL_PROJ_FILE" ^
/p:SqlPublishProfilePath="PATH_TO_PUBLISH_PROFILE" ^
/p:UpdateDatabase=False ^
/t:Build,Publish
Related
I'm trying to automate the initialising of a SQL DB on Azure. For some (lookup) tables, data needs to be copied from a source DB into the new DB each time it is initialised.
To do this I execute a query containing
SELECT * INTO [target_db_name]..[my_table_name] FROM [source_db_name].dbo.[my_table_name]
At this point an exception is thrown telling me that
Reference to database and/or server name in 'source_db_name.dbo.my_table_name'
is not supported in this version of SQL Server.
Having looked into this, I've found that it's now possible to reference another Azure SQL DB provided it has been configured as an external data source. [here and here]
So, in my target DB I've executed the following statement:
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<password>';
CREATE DATABASE SCOPED CREDENTIAL cred
WITH IDENTITY = '<username>',
SECRET = '<password>';
CREATE EXTERNAL DATA SOURCE [source_db_name]
WITH
(
TYPE=RDBMS,
LOCATION='my_location.database.windows.net',
DATABASE_NAME='source_db_name',
CREDENTIAL= cred
);
CREATE EXTERNAL TABLE [dbo].[my_table_name](
[my_column_name] BIGINT NOT NULL
)
WITH
(
DATA_SOURCE = [source_db_name],
SCHEMA_NAME = 'dbo',
OBJECT_NAME = 'my_table_name'
)
But the SELECT INTO statement still yields the same exception.
Furthermore, a simple SELECT * FROM [source_db_name].[my_table_name] yields the exception "Invalid object name 'source_db_name.my_table_name'".
What am I missing?
UPDATE
I've found the problem: CREATE EXTERNAL TABLE creates what appears to be a table in the target DB. To query this, the source DB name should not be used. So where I was failing with:
SELECT * FROM [source_db_name].[my_table_name]
I see that I should really be querying
SELECT * FROM [my_table_name]
It looks like you might need to define that external table, according to what appears to be the correct syntax:
CREATE EXTERNAL TABLE [dbo].[source_table](
...
)
WITH
(
DATA_SOURCE = source_db_name
);
The three part name approach is unsupported, except through elastic database query.
Now, since you're creating an external table, the query can pretend the external table is an object native to our [target_db]- this allows you to write the query SELECT * FROM [my_table_name], as you figured out from your edits. From the documentation, it is important to note that "This allows for read-only querying of remote databases." So, this table object is not writable, but your question only mentioned reading from it to populate a new table.
As promised, here's how I handle database deploys for SQL Server. I use the same method for on-prem, Windows Azure SQL Database, or SQL on a VM in Azure. It took a lot of pain, trial and error.
It all starts with SQL Server Data Tools, SSDT
If you're not already using SSDT to manage your database as a project separate from your applications, you need to. Grab a copy here. If you are already running a version of Visual Studio on your machine, you can get a version of SSDT specific for that version of Visual Studio. If you aren't already running VS, then you can just grab SSDT and it will install the minimal Visual Studio components to get you going.
Setting up your first Database project is easy! Start a new Database project.
Then, right click on your database project and choose Import -> Database.
Now, you can point at your current development copy of your database and import it's schema into your project. This process will pull in all the tables, views, stored procedures, functions, etc from the source database. When you're finished you will see something like the following image.
There is a folder for each schema imported, as well as a security folder for defining the schemas in your database. Explore these folders and look through the files created.
You will find all the scripts created are the CREATE scripts. This is important to remember for managing the project. You can now save your new solution, and then check it into your current source control system. This is your initial commit.
Here's the new thought process to managing your database project. As you need to make schema changes, you will come into this project to make changes to these create statements to define the state you want the object to be. You are always creating CREATE statements, never ALTER statements in your schema. Check out the example below.
Updating a table
Let's say we've decided to start tracking changes on our dbo.ETLProcess table. We will need columns to track CreatedDateTime, CreatedByID, LastUpdatedDateTime, and LastUpdatedByID. Open the dbo.ETLProcess file in the dbo\Tables folder and you'll see the current version of the table looks like this:
CREATE TABLE [dbo].[ETLProcess] (
[ETLProcessID] INT IDENTITY (1, 1) NOT NULL
, [TenantID] INT NOT NULL
, [Name] NVARCHAR (255) NULL
, [Description] NVARCHAR (1000) NULL
, [Enabled] BIT DEFAULT ((1)) NOT NULL
, CONSTRAINT [PK_ETLProcess__ETLProcessID_TenantID]
PRIMARY KEY CLUSTERED ([ETLProcessID], [TenantID])
, CONSTRAINT [FK_ETLProcess_Tenant__TenantID]
FOREIGN KEY ([TenantID])
REFERENCES [dbo].[Tenant] ([TenantID])
);
To record the change we want to make, we simply add in the columns into the table like this:
CREATE TABLE [dbo].[ETLProcess] (
[ETLProcessID] INT IDENTITY (1, 1) NOT NULL
, [TenantID] INT NOT NULL
, [Name] NVARCHAR (255) NULL
, [Description] NVARCHAR (1000) NULL
, [Enabled] BIT DEFAULT ((1)) NOT NULL
, [CreatedDateTime] DATETIME DEFAULT(GETUTCDATE())
, [CreatedByID] INT
, [LastUpdatedDateTime] DATETIME DEFAULT(GETUTCDATE())
, [LastUpdatedByID] INT
, CONSTRAINT [PK_ETLProcess__ETLProcessID_TenantID]
PRIMARY KEY CLUSTERED ([ETLProcessID], [TenantID])
, CONSTRAINT [FK_ETLProcess_Tenant__TenantID]
FOREIGN KEY ([TenantID])
REFERENCES [dbo].[Tenant] ([TenantID])
);
I didn't add any foreign keys to the definition, but if you wanted to create them, you would add them below the Foreign Key to Tenant. Once you've made the changes to the file, save it.
The next thing you'll want to get in the habit of is checking your database to make sure it's valid. In the programming world, you'd run a test build to make sure it compiles. Here, we do something very similar. From the main menu hit Build -> Build Database1 (the name of our database project).
The output window will open and tell you if there are any problems with your project. This is where you'll see things like Foreign keys referencing tables that don't yet exist, bad syntax in your create object statements, etc. You'll want to clean these up before you check your update into source control. You'll have to fix them before you will be able to deploy your changes to your development environment.
Once your database project builds successfully and it's checked in to source control, you're ready for the next change in process.
Deploying Changes
Earlier I told you it was important to remember all your schema statements are CREATE statements. Here's why: SSDT gives you two ways to deploy your changes to a target instance. Both of them use these create statements to compare your project against the target. By comparing two create statements it can generate ALTER statements needed to get a target instance up to date with your project.
The two options for deploying these changes are a T-SQL change script, or dacpac. Based on the original post, it sounds like the change script will be most familiar.
Right click on your database project and choose Schema Compare.
By default, your database project will be the source on the left. Click Select target on the right, and select the database instance you want to "upgrade". Then click Compare in the upper left, and SSDT will compare the state of your project with the target database.
You will then get a list of all the objects in your target database that are not in the project (in the DROP section), a list of all objects that are different between the project and target database (in the ALTER Section), and a list of objects that are in your project and not yet in your target database (in the ADD section).
Sometimes you'll see changes listed that you don't want to make (changes in the Casing of your object names, or the number of parenthesis around your default statements. You can deselect changes like that. Other times you will not be ready to deploy those changes in the target deployment, you can also deselect those. All items left checked will either be changed in target database, if you choose update (red box below), or added to your change script (green box below), if you hit the "Generate Script" icon.
Handling lookup data in your Database Project
Now we're finally to your original question, how do I deploy lookup data to a target database. In your database project you can right click on the project in Solution Explorer and choose Add -> New Item. You'll get a dialog box. On the left, click on User Scripts, then on the right, choose Post-Deployment Script.
By adding a script of this type, SSDT knows you want to run this step after any schema changes. This is where you will enter your lookup values, as a result they're included in source control!
Now here's a very important note about these post deployment scripts. You need to be sure any T-SQL you add here will work if you call the script in a new database, in an existing database, or if you called it 100 times in a row. As a result of this requirement, I've taken to including all my lookup values in merge statements. That way I can handle inserts, updates, and deletes.
Before committing this file to source control, test it in all three scenarios above to be sure it won't fail.
Wrapping it all up
Moving from making changes directly in your target environments to using SSDT and source controlling your changes is a big step in the maturation of your software development life-cycle. The good news is it makes you think about your database as part of the deployment process in a way that is compatible with continuous integration/continuous deployment methods.
Once you get used to the new process, you can then learn how to add a dacpac generated from SSDT into your deployment scripts and have the changes pushed at just the right time in your deployment.
It also frees you from your SELECT INTO problem, your original problem.
I am using the GUI (hsqldb.jar) in HSQLDB 2.2.9 to create a DB. I have all the SQL commands in a separate text file. So to create the DB, I just copy the text and paste into the HSQLDB editor and hit the "Execute SQL" button. I have successfully created my DB several times with different revisions, each time executing the CREATE TABLE commands with one press of the "Execute SQL" button, and the INSERT INTO commands with a subsequent press of the "Execute SQL" button. This works, but it would be more convenient to execute both the CREATE and the INSERT commands at the same time. I've tried to combine these into one "Execute SQL", but I keep getting this error:
user lacks privilege or object not found: SHOP / Error Code: -5501 / State: 42501
Here's what I've tried:
CREATE TABLE Shop (
Id int NOT NULL IDENTITY,
Name varchar(255) NOT NULL,
UNIQUE (Name)
)
INSERT INTO Shop VALUES (
NULL,
'Test Shop'
)
Note that this exact same code works if I execute the SQL in two separate steps. I've tried putting COMMIT between the CREATE and the INSERT commands, as well as CHECKPOINT, but neither of these solved the problem. I also tried adding SET WRITE_DELAY FALSE at the top, but this didn't solve it either.
What do I need to add to this code to make it work in one step? Thanks!
This is not possible.
The GUI client sends all the text in the window to the database engine. The engine compiles all the statements before executing them. Because of this, if a statement relies on the completion of a previous statement, it won't compile.
The better way to populate your database from a script is the SqlFile tool which is part of SqlTool.jar. This tool executes statements one by one.
The separate Guide is here:
http://hsqldb.org/doc/2.0/util-guide/sqltool-chapt.html
How do I create a table in SQL Server from a .sql? I see the query statements and the data to be inserted into the table but how do I create the actual tables?
If the statements to create the tables aren't in the .sql file, then you will need to know their structure and create them, either by using a handwritten query, another .sql file or SQL Server Management Studio (SSMS).
In SSMS you can expand a database in the Object Explorer and then right click on "Tables" to select "New Table..." then you will get a UI for defining the columns you need.
With the context of your previous question you need to contact whoever supplied the .sql files and ask for a script to create the required tables. Or perhaps they should send you a copy(a backup) of the database.
You can run it from the command prompt using the command below:
sqlcmd -S myServer\instanceName -i C:\myScript.sql
http://msdn.microsoft.com/en-us/library/ms170572.aspx
This assumes that your .sql files contains the logic to create the needed tables.
You can create tables from a sql script like so.
CREATE TABLE MyTable1 (
MyString1 NVARCHAR(50) NOT NULL,
MyInt1 INT NULL NULL
)
GO
CREATE TABLE MyTable2 (
Id INT IDENTITY(1,1) NOT NULL,
Name NVARCHAR(50) NOT NULL,
PRIMARY KEY(Id)
)
GO
See http://msdn.microsoft.com/en-US/library/ms174979%28v=SQL.90%29.aspx for more info
I wanted to modify a column in a sql server 2005 table to IDENTITY(1,1)
Incidentally this table is empty and the column to be changed is a primary key.
This column is also a foreign key for two other tables.
After googling I found that you cannot use Alter table syntax to modify a column and make it an indentity column.
Link #1 : How do I add the identity property to an existing column in SQL Server
Link #2 : Adding an identity to an existing column -SQL Server
I ended up checking the dependent tables (2 of them) removing the foreign keys (generated the script from SSMS) then dropping the main table then re-creating with identity. (could try the rename option here as well)
Then re-created the foreign keys for the earlier dependent two tables.
But all this was manual work, any scripts or SPs out there to make this easier.
Ideally all these steps would be done by such a script/tool/utility:
Check dependent tables keys
Generate Create and drop foreign key scripts for this
Generate create script for the main table
drop the main table (or rename the table if the table has data)
re-create the table with identity column enabled
re-create foreign keys
You can use SSMS to generate a script (Edit a table, save script), but otherwise it's a manual process as you identified.
The SSMS scripts will pick up dependencies etc. For this kind of work, I tend to use SSMS to generate a basic script, pimp it a bit, run it carefully, then use a comparison tool (such as Red Gate compare) to generate a safer version.
Edit: The SSMS error is not an error, it's a safety check that can be switched off
(This is merely a follow-up to gbn's post with more details -- it isn't all that easy to figure this stuff out.)(
It isn't impossible to write a utility to do this, just very complex and very hard. Fortunately, Microsoft has already done it -- its called SSMS (or SMO?). To generate such a script:
In the Object Explorer, drill down to the database and table that you want to modify
Right click and select Design
Make the desired changes to the one table in the design screen. It's reasonably intuitive.
To add/remove the identity property, select the column in the upper pane, and in the lower pane/"Column Properties" tab, expand and configure the settings under "Identity Specification".
To generate a script to implement all your changes, incorporating all the dependent key changes, click on the "Generate Change Script" toolbar button. This is also an option under the "Table Designer" menu.
I also do this to generate scripts (that I later modify--SSMS doesn't always produce the most efficient code.) Once done, you can exit out without saving your changes -- leaving you a DB you can test your new script on.
drop the pk and build the same datatype column
copy the data of the column which you want to set identity to the new column.
drop the old column
reset primary key
ALTER TABLE UserRole
DROP CONSTRAINT PK_XX
ALTER TABLE XX
ADD newX int not null identity(1,1) primary key
update XX set newX = oldX
alter table XX
DROP COLUMN oldX
this is the simplest way to set identity column.
if you don't want to use the long generated script.
I'm trying to change the size of a column in sql server using:
ALTER TABLE [dbo].[Address]
ALTER COLUMN [Addr1] [nvarchar](80) NULL
where the length of Addr1 was originally 40.
It failed, raising this error:
The object 'Address_e' is dependent on column 'Addr1'.
ALTER TABLE ALTER COLUMN Addr1 failed because one or more objects access
this column.
I've tried to read up on it and it seems that because some views are referencing this column and it seems that SQL Server is actually trying to drop the column that raised the error.
Address_e is a view created by the previous DB Administrator.
Is there any other way I can change the size of the column?
ALTER TABLE [table_name] ALTER COLUMN [column_name] varchar(150)
The views are probably created using the WITH SCHEMABINDING option and this means they are explicitly wired up to prevent such changes. Looks like the schemabinding worked and prevented you from breaking those views, lucky day, heh? Contact your database administrator and ask him to do the change, after it asserts the impact on the database.
From MSDN:
SCHEMABINDING
Binds the view to the schema of the underlying table or tables. When
SCHEMABINDING is specified, the base
table or tables cannot be modified in
a way that would affect the view
definition. The view definition itself
must first be modified or dropped to
remove dependencies on the table that
is to be modified.
If anyone wants to "Increase the column width of the replicated table" in SQL Server 2008, then no need to change the property of "replicate_ddl=1". Simply follow below steps --
Open SSMS
Connect to Publisher database
run command -- ALTER TABLE [Table_Name] ALTER COLUMN [Column_Name] varchar(22)
It will increase the column width from varchar(x) to varchar(22) and same change you can see on subscriber (transaction got replicated). So no need to re-initialize the replication
Hope this will help all who are looking for it.
See this link
Resize or Modify a MS SQL Server Table Column with Default Constraint using T-SQL Commands
the solution for such a SQL Server problem is going to be
Dropping or disabling the DEFAULT Constraint on the table column.
Modifying the table column data type and/or data size.
Re-creating or enabling the default constraint back on the sql table column.
Bye
here is what works with the version of the program that I'm using: may work for you too.
I will just place the instruction and command that does it. class is the name of the table. you change it in the table its self with this method. not just the return on the search process.
view the table class
select * from class
change the length of the columns FacID (seen as "faci") and classnumber (seen as "classnu") to fit the whole labels.
alter table class modify facid varchar (5);
alter table class modify classnumber varchar(11);
view table again to see the difference
select * from class;
(run the command again to see the difference)
This changes the the actual table for good, but for better.
P.S. I made these instructions up as a note for the commands. This is not a test, but can help on one :)
Check the column collation. This script might change the collation to the table default. Add the current collation to the script.
You can change the size of the column in 3 steps:
Alter view Address_e and take in comment column /*Addr1*/
Run your script
ALTER TABLE [dbo].[Address]
ALTER COLUMN [Addr1] [nvarchar](80) NULL
Then again alter view Address_e, in order to uncomment column Addr1