I use INFORMATON_SCHEMA.TABLE_CONSTRAINTS in a stored procedure to dynamically generate a uniqueness check on the tables.
It works fine until I have a constraint that refers to a table that does not exist or no longer exists.
Have you ever been confronted with this situation? Is there a way to clean the information_schema
thanks
Join to SNOWFLAKE.ACCOUNT_USAGE.TABLES, you'll find column DELETED there, use it for filtering.
Related
I have a script for microsoft sql server database which has hundreds of tables and tables contains data as well. This is the database of a web application.what I want to do is to delete the previous records and reset the primary key to 1 or 0.
I have tried
`DBCC CHECKIDENT ('dbo.tbl',RESEED,0); `
but it does not work for me as in most of the tables the primary key is not identity.
I can not truncate the table as its primary key is being used as FK in many other tables.
I have also tried to add the identity specification in the primary key of the table and run the checkident query and then changing it back to non-identity spec, but after adding the record again it starts from where it left.
Making changes in the code is not an option for me.
please help.
According with your question I am not sure about the main objective, Why? If you need truncate a lot of tables and change their structures to have an Identity property why you can't disabled the FK? . In the past I have used an standard process for rebuild a table and migrate all the information, this represent a group of steps, I would try to help you but you should follow the next steps.
Steps:
1) Disable FK for alter the structure of your tables. You can get the solution for this task in the next link:
Temporarily disable all foreign key constraints
2) Alter the table with the new property Identity, this is a classic process of ALTER TABLE xxxxxx.
3) Execute the syntax that previously posted :
DBCC CHECKIDENT ('dbo.tbl',RESEED,0);
Try to follow this path and if you have any problem only ask us.
You can not truncate table that have relation. You shoud remove relation firstly.
My understanding of this question:
You have a database with tables that you want to empty and next have them use primary key values starting at 0 or 1.
Some of these tables use an identity value and you already have a solution for those (you know you can find out which columns have an identity by using the sys.columns view? Look for the is_identity column).
Some tables do not use an identity but get their pk values from an unknown source, which we can't modify.
The only solution I see, is creating an after insert trigger (or modifying) on those tables that subtracts from the new pk value.
E.g.: your "hidden generator" will generate a next value 5254, but you want the next pk value to become one:
CREATE TRIGGER trg_sometable_ai
ON sometable
AFTER INSERT
AS
BEGIN
UPDATE st
SET st.pk_col = st.pk_col - 5253
FROM sometable AS st
INNER JOIN INSERTED AS i
ON i.pk_col = th.pk_col
END
You'll have to determine the next value and thus the "subtract value" for each table.
If the code also inserts child records into tables with a foreign key to this table, and uses the previously generated value, you have to modify those triggers as well...
This is a "last resort" solution and something I would recommend against in any scenario that has other options. Manipulating primary key values is generally not a good idea.
I've got a table in a legacy non-sql program that has a routine to copy the data into a SQL Server database. The developer of this system wrote the routine with no documentation to see what is happening under the hood. One table I attempted to move ended up failing, now when I try to copy this table over I get the following error:
Unable to create table 'CR_Receipt_Payment_Details'
42S01: [Microsoft][ODBC SQL Server Driver][SQL Server] There is
already an object named 'byReceipt_RECPMT' in the database.
I know that I need to delete this object so that the process can run. I tried running
Drop Table byReceipt_RECPMT
and have the following output:
Cannot use DROP TABLE with 'byReceipt_RECPMT' because 'byReceipt_RECPMT' is a constraint. Use ALTER TABLE DROP CONSTRAINT.
I'm not sure where to go from here.
Can someone point me in the direction of how to find and drop this object?
Thanks.
If the table already exists, then you want to do this:
ALTER TABLE CR_Receipt_Payment_Details DROP CONSTRAINT byReceipt_RECPMT
However, the problem may be that there is a constraint with that name on a DIFFERENT table. You need to find out what table that is. Or else, rename the constraint for THIS table.
This means that your database has a constraint (primary key, foreign key, check, etc.) named byReceipt_RECPMT. Because that name is being used by a constraint, it can't be used by a table.
You could drop the constraint, but so far the only reason you have is that you want to use its name for a table. That's not good enough. If you investigate the constraint and find that it's incorrect or that you don't need it, by all means drop it - Ross Presser's answer shows how to do so.
If you do need the constraint, either rename the constraint or use a different table name. To rename a constraint, use the sp_rename system stored procedure:
sp_rename 'CR_Receipt_Payment_Details.byReceipt_RECPMT', 'new constraint name'
sp_rename documentation (There are examples in the section titled "Renaming constraints").
I have a data table with a primary key called OptDefID. When a record in this table is deleted I need to go and delete all records from the Permissions table that have that OptDefID in the defID field (in Permissions). The tricky part for me is that the Permissions table does not have a primary key and holds lots of different kinds of permissions, and has a permissiontype field. I need to delete rows that have the OptDefID AND a permissiontype of OptDef.
Because I need to consider the permissiontype, I don't believe a Foreign Key Constraint is appropriate here (or is it?).
I've also considered creating a trigger, but am unsure how to get the OptDefID passed into the trigger.
I can do this via the application itself, but I feel like this should be a database level solution.
What's the best solution?
Say I want to delete from Permissions where defID is 20 and permissiontype is 'OptDef'. There may be another row in Permissions that has a defID of 20, but has a permissiontype of 'Member'. That show should not be deleted because it pertains to Members and not Opt data.
Storing table names in fields prevents foreign keys from working properly, as you have discovered.
I recommend you fix the root problem and separate these two foreign keys, so each of them can be individually enforced. For example:
CREATE TABLE Permissions (
...
OptDefId int,
MemberId int,
FOREIGN KEY (OptDefId) REFERENCES OptDef ON DELETE CASCADE,
FOREIGN KEY (MemberId) REFERENCES Members ON DELETE CASCADE,
CHECK (
(OptDefId IS NOT NULL AND MemberId IS NULL)
OR (OptDefId IS NULL AND MemberId IS NOT NULL)
)
)
The CHECK makes sure only one of the FKs is non-NULL and only non-NULL FKs are enforced.
Alternatively, you could avoid changing your current design and enforce this "special" FK through a trigger, but declarative constraints should be preferred to triggers when possible - declarative constraints tend to leave less room for error and be more "self-documenting".
In case the OptDefId column is only filled when the record in question references the Permissions table, a foreign key should be appropriate. I.e. you have another column MemberId, which in turn could be a foreign key on a Members table.
It is only when you have a single column - let's call it ObjectId - which takes on other meanings as the contents of the type column change, that you cannot use foreign keys.
In that case, a trigger would probably be the best approach, as you already guessed. I only know about triggers in Oracle PL/SQL, where they are passed in as separate, complete rows representing the old and new state. I guess it will be analogous in MS-SQL-Server.
In addition to using join with SELECT statements, you can also join multiple tables in DELETE & UPDATE statements as well.
As I understand the issue, you should be able to join the Permissions table to the table with the OptDefID column & add a WHERE clause similar to the this:
DELETE MyTable
...
WHERE [Permissions].permissiontype = 'OptDef'
Also, these links may be of interest too:
SQL DELETE with JOIN another table for WHERE condition (for MySQL, but still relevant)
Using A SQL JOIN In A SQL DELETE Statement
Using A SQL JOIN In A SQL UPDATE Statement
I need a simple resize of a column from VARCHAR(36) to VARCHAR(40).
If you try to use SQL Server Enterprise Manager, the script it generates is effectively creating a new table with the new structure, inserting all of the data from the existing table into it, dropping the existing table, renaming the new table, and recreating any indexes.
If you read the documentation (and many online resources including SO), you can use an ALTER statement for the resize.
Does the ALTER affect the way the data is stored in any way? Indexes? Statistics? I want to avoid performance hits because of this modification due to the fact that the table can get large.
Just use ALTER TABLE. SSMS is a bit, er, stupid sometimes
You'll need to drop and recreate dependent constraints (FK, unique, index, check etc)
However, this is only a metadata change and will be very quick for any size table (unless you also change NOT NULL to NULL or varchar to nvarchar or such)
No, ALTER TABLE (http://msdn.microsoft.com/de-de/library/ms190273.aspx) is the way how Microsoft intended to do this kind of change.
And if you do not add extra options to your command, no indexes or statistics should get harmed.
A possibility of data loss is also not given, because you are just making the column bigger.
Everything should be fine.
Changes to database structure should NEVER be made using SSMS on a porduction environment for just the reason you brought up. It can destroy performance in a large table. ALTER table is the prefered method, it is faster and it can be stored in source control as a change to push to prod after testing.
Following should be the better way to handle this
IF EXISTS (SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '<tablename>'
AND COLUMN_NAME = '<field>')
BEGIN
ALTER TABLE <tablename> ALTER COLUMN [<field>] varchar(xxxx) null
END
ELSE
So, first off, we're using a history system where there's a history version of all of our tables. I'm adding a new column to a table, so I add it to both the dbo and the hist versions. I add a constraint that the default should be 0. However, I misspelled the column for the hist table. So, I add the correct one, and go to drop the incorrect one. However, it's saying The object 'DF__FCRelease__NumRe_125D4E50' is dependent on column 'NumRelease'. This is the constraint I mentioned above. I've tried deleting it though SQL, which claims it completes successfully, but the constraint remains. I've tried deleting it through the GUI, but it claims the object does not exist. Here's the SQL I attempted to use to delete the constraint:
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF__FCRelease__NumRe__125D4E50]') AND type = 'D')
BEGIN
ALTER TABLE [hist].[FCRelease] DROP CONSTRAINT [DF__FCRelease__NumRe__125D4E50]
END
Any ideas?
This, I believe, is related to a similar question. So, I'll give you a similar answer.
You probably need rebuild your master database. I suspect that there is some corruption there that is causing this issue.
As a workaround, you could try removing the column, re-adding it, and then re-adding the constraint (a la here). That might fix the problem as well.