How do I properly use CONSTRAINTS_AS_ALTER for GET_DDL? - database

exec dbms_metadata.set_transform_param(DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS_AS_ALTER', TRUE);
SELECT DBMS_METADATA.GET_DDL(object_type, object_name, owner) FROM all_OBJECTS WHERE
OWNER = 'USERNAME' AND OBJECT_TYPE = 'TABLE';
When I run these commands, unfortunately I am getting the alter statements after each table. I would prefer to have the DDL generated for all of my tables, then have that followed by the alter statements to set up the constraints. Currently, the alter statement runs and fails for some tables because the table being referenced has not been created yet.
I have seen this command:
select dbms_metadata.get_ddl('CONSTRAINT',constraint_name) from user_constraints;
But to use that wouldn't I have to somehow tell GET_DDL to not generate any constraints at all?
Is there some way to just make the tables created in the right order?
Thanks!

You can tell GET_DDL to not generate referential integrity constraints by running:
exec dbms_metadata.set_transform_param(DBMS_METADATA.SESSION_TRANSFORM, 'REF_CONSTRAINTS', FALSE);
Then run the constraint DDL, but only where constraint_type = 'R'. (You do not want to run all of the constraints separately, else you will need to generate the primary keys before the foreign keys, and run into the same dependency issue.)
See here for the list of transform parameters.

Related

Creating procedure won't recognize DB

I'm trying to create and execute a procedure that creates some tables. It won't recognize my database.
USE [db1]
go
create procedure version_1 as
update db1
set ver=1
where ver=0;
create table Staff_Titles(
title nvarchar(100) not null,
title_description nvarchar(200) null,
[..]
go
It compiles even though the db1 from update db1 is underlined. So is ver=1 and ver=0. After I try to execute it, it says
invalid object name
at USE [DB1] again even though, it's inside the stored procedures...
I tried refreshing the database, I tried looking for Edit -> IntelliSense but I can't find it, I tried Ctrl + shift + R, nothing worked.
The IntelliSense is telling you that it can't find a table called db1 in the db1 database. Make sure the table exists or if it's in a different schema, make sure to include the schema, like this:
update db1.schmaname.db1
set ver=1
where ver=0;
If you are trying to store version data, you have to add a table and a field to store this information. You can not update fields on a database, as there are no fields directly at the database level. You can create a table called "Versions" with a field called "ver".
CREATE TABLE Versions
(
[Ver] [int] NOT NULL,
CONSTRAINT [PK_Versions] PRIMARY KEY CLUSTERED (Ver ASC)
)
Then when you run the procedure it could insert a record to indicate that the tables have been updated with that version. Something like this:
insert into Versions
values (1)
Then if you ever need to query for the latest version you could use:
select max(Ver) Ver from Versions
You might want to try and clear the intellisense cache if you "just" created that Database. Use the keystroke Ctrl-Shift-R or Ctrl-R.

What is the purpose of including CHECK CONSTRAINT & GO in the generated database schema script

I am working on SDL Server 2008 R2, where I generated a schema-only database script. The generated script is as follows:
ALTER TABLE [dbo].[ConsoleServer] WITH CHECK ADD CONSTRAINT [FK_ConsoleServer_RackUnits] FOREIGN KEY([RackUnitID])
REFERENCES [dbo].[RackUnits] ([UnitID])
GO
ALTER TABLE [dbo].[ConsoleServer] CHECK CONSTRAINT [FK_ConsoleServer_RackUnits]
I have these 2 questions:-
I know that the first line is responsible to create a FK between two DB tables. but what is the purpose of the following :
ALTER TABLE [dbo].[ConsoleServer] CHECK CONSTRAINT [FK_ConsoleServer_RackUnits]
In general, why does the DB script have the word GO. Now if I remove it the script will be executed well on the destination DB, so why it is included in the script prior to any statement?
The ALTER TABLE ... CHECK CONSTRAINT ... line enables the constraint. You can add a constraint and leave it disable (while you clean up the data for example). See more here
GO is a batch separator, it's only recognized by SSMS. Some statements, such as CREATE PROCEDURE... requires it to be the first statement in the batch. You can type it out in a new file, or use GO to terminate the previous batch. Don't send GO from your application through OLEDB or ADO.NET though.

How to delete all data in each tables on my database

I have a database which consist of 300 tables with data in it. I need to delete all the data inside each tables. I tried to truncate all tables but then I got an error that the process could not be completed because one of the column in a table is a foreign key. Is there other way to resolve my problem? Thanks.
You need to either:
remove all the foreign keys, truncate, then re-create FKs;
disable all the foreign keys, delete (not truncate), then re-enable FKs; or,
delete from child tables first.
The latter may not be possible if you're lucky enough to have circular references, and it can still be complicated even without circular references. The first two are also relatively complex, but I solved a very similar problem for a different user recently (and I find these easier than trying to determine the proper delete order):
Temporarily disable all foreign key constraints
Another idea is to perform a simpler and more complete wipe:
script the tables (and other objects obviously), drop the database and re-create it; or,
create a copy of the database, and use Visual Studio / SSDT or a 3rd party schema comparison tool to create all of the objects in the empty database (then you can drop the old database and rename the new one).
Try this : A quick way of doing it .sp_msforeachtable is an undocumented SP so there's a risk in using them. I came up with this answer using Aaron Logic by disabling the constraints used in his answer.
use [YourDB]
Go
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'Truncate Table ?'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'

Truncate all tables of a database in SQL Server 2005

How can I truncate all tables of a database?
Why would you want to truncate all tables? If you want an empty database, why not run the CREATE script of the database?
If you want to Truncate a table referenced by a foreign key, you will have to drop the FK constraint first. Disabling constraints is something that is not possible anymore in recent versions of SQL Server.
You can see this post : how-do-you-truncate-all-tables-in-a-database-using-tsql
I use the script
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
GO
Reset Auto-Increment? I'm not sure if you understand correctly how this works.
Primary Key incrementing is handled by SQL Server using the IDENTITY specification. If your tables have got no data in them, it will always start from 0.
If I were you, I'd go have a flick through your programming books and pick up some basic database knowledge as it sounds like you're missing some fundamental facts there.

Why would IF EXISTS not work?

I have a lot of code I am trying to run where I'm querying the sysobjects table to check if an object exists before I drop it and create it again.
Issue being, sometimes if I go:
if not exists (select name from sysobjects o where o.name = 'my_table' and o.type = 'U')
CREATE TABLE my_table (..)
go
it works, no worries. However, when I came back to run it again, I get this lovely error:
SQL Server Error on (myserver) Error:2714 at Line:10 Message:There is already an object named 'my_table' in the database.
Thanks for that, SQL Programmer. I actually asked for you not to create this table if it already exists. -_-
Any ideas?
the logic to what you are doing doesn't seem quite right. based on your statement:
"I am trying to run where I'm querying the sysobjects table to check if an object exists before I drop it and create it again"
you should simply do a delete followed by a create. This way is usually better because it ensures that the table will be updated. if the table existed and you had changes, you are probably not getting what you want.
The immediate issue you are running into is an assumed db ownership that was not consistent between runs.
based on your clarification below - here is what you can do:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[XXXX]') AND type in (N'U'))
DROP TABLE [dbo].[XXXX]
GO
CREATE TABLE [dbo].[XXXX(...
GO
you can run this over and over again...
The sybase parsers object validation pass is global and not based on conditional evaluation. Even though your code can not execute CREATE TABLE the statement is still checked for syntax and applicability which fails when the system sees that the table already exists.
The only way around this that I know of is to put your create statements inside of an EXEC() which would be evaluated only if the section was executed.
yes, the entire batch of SQL is normalized and compiled so as to create an "execution plan" for the entire batch. During normalization, the "possible" "create table" statement is a problem if it already exists at compile time.
My solution: rename -
if exists (select 1 from ....)
begin
drop table xyz
create table xyz_zzzz ( ... )
exec sp_rename 'xyz_zzzz','xyz'
end

Resources