SQL Server : drop default constraint, alter column and recreate constraint - sql-server

Is it possible and how to alter column with default constraint ?
The problem: I want to invoke this alter:
For example
ALTER TABLE MY_TABLE
ALTER COLUMN MY_COLUMN nvarchar(1024); --(was varchar)
But this code throws an exception:
[S0001][5074] Line 1: The object 'DF__MY_TABLE __MY_COL__2A563856' is dependent on column 'MY_COLUMN '.
I know how to search for that constraint:
select c.name, col.name
from sys.default_constraints c
inner join sys.columns col on col.default_object_id = c.object_id
inner join sys.objects o on o.object_id = c.parent_object_id
inner join sys.schemas s on s.schema_id = o.schema_id
where o.name = 'MY_TABLE' and col.name = 'MY_COLUMN'
and now I not only want to drop the constraint that blocks the execution of the above alter but also recreate this constraint.
I have 100 columns like that so I want to write some procedure or function and call it 100 times in script for each table and command separately.
Moreover some columns would have default values like '' or '-' or no default value at all. It is important that after scripts execution all constraints would be as before execution and none of them would be missing.

Related

Filter table in long format i.e. keep rows if condition in group is satisfied

I want to query and see which table do not have a column called hello.
I first use a query from this question: Find all tables containing column with specified name - MS SQL Server
SELECT c.name AS 'ColumnName'
,t.name AS 'TableName'
,c.object_id
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE t.name in (select colname from someTable) -- table with one column containing table names.
So this gives me a table in long format i.e. every table has many rows. Now I want figure out which table does not have a column called hello.
Here an example for the query with a cte. However, you have to consider that the same table name might exist in different schemas, so if you work with schemas you should add a join to sys.schemas and include this in your query:
WITH cteColTabs AS(
SELECT t.name AS TableName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE t.name in (select colname from someTable) -- table with one column containing table names.
AND c.name = N'hello'
)
SELECT t.Name AS TableName
FROM sys.tables t
LEFT JOIN cteColTabs ct ON ct.TabName = t.Name
WHERE ct.TableName IS NULL

How to find in which tables a column from another table is used either as a foreign key column or normal column in SQL Server

I wanted to know all the tables where the column from another table is used as a foreign key or normal key.
For example: list all the tables where the tran_id column from the table Transactions is used. tran_id can either be a foreign key or just a normal column.
I tried using the following query but it returns tables with foreign key constraints only.
SELECT
OBJECT_NAME(f.parent_object_id) TableName,
COL_NAME(fc.parent_object_id, fc.parent_column_id) ColName
FROM
sys.foreign_keys AS f
INNER JOIN
sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN
sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
WHERE
OBJECT_NAME (f.referenced_object_id) = 'YourTableName'
Any help? Thanks in advance.
You could use a query like this:
select tab.name, col.name
from sys.columns col
inner join sys.tables tab
on col.object_id = tab.object_id
WHERE col.name = 'tran_id'
You would then have to manually find the relevant implicit FKs.
Is RI enforced partly by the logic tier and not always by the database server?

Cannot delete primary key constraint in SQL Server

When I open designer for a table in SSMS, first column Id has a primary key assigned to it (IDENTITY), and key icon is shown next to it. In the Indexes / Keys window I can see a PK_dbo.Lines entry with Name [PK_dbo.Lines] and type Primary Key.
ALTER TABLE dbo.Lines DROP CONSTRAINT [PK_dbo.Lines]
returns
Msg 3728, Level 16, State 1, Line 33
'PK_dbo.Lines' is not a constraint.
If I execute
SELECT *
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
I can see primary keys for all tables, except for table Lines...
This query also does not return any results:
select object_name (parent_obj) ObjectName, name
from sysobjects
where xtype = 'PK'
and parent_obj = (object_id('[dbo].[Lines]'))
Any idea what is going on here?
If you make any changes to tables / columns in a database SSMS needs to be manually refreshed in order to correctly reflect these changes. Could it be that it is as simple as right-clicking on Tables and select refresh?
Alternatively, you might have spelled the PK name incorrectly? Please try the following script to remove the PK from the table 'Lines':
declare #PK_Name nvarchar(200);
declare #strSQL nvarchar(max);
select #PK_Name = (
select i.name as IndexName
from sys.indexes as i
inner join sys.index_columns as ic
on i.object_id = ic.object_id
and i.index_id = ic.index_id
inner join sys.tables as t
on t.object_id = i.object_id
where i.is_primary_key = 1
and t.name = N'Lines'
)
set #strSQL = N'ALTER TABLE dbo.Lines DROP CONSTRAINT ' + #PK_Name
execute(#strSQL)
First the script retrieves the correct name for the PK and then it tries to drop the PK constraint.

SQL Server 2012: Constraint has NULL for name. How can I drop this?

I am not sure how this happened, but I have a PRIMARY KEY constraint on one of my tables and the name is NULL. I discovered it because I had to drop/recreate the table, and when I tried to add the PRIMARY KEY, the system responded that the constraint already existed.
I executed the following:
SELECT i.object_id, i.name, i.type_desc
FROM sys.indexes i
INNER JOIN sys.tables t ON i.object_id = t.object_id
AND t.name = N'Organization'
and the result is:
object_id name type_desc
1570377655 NULL HEAP
1570377655 IX_Organization_OwnedByOrganizationId NONCLUSTERED
I tried dropping and recreating the table several times and each time the index is there. How can I drop the constraint?
You can try to find the index you are trying to add using the following query:
SELECT [Table] = t.[name]
, [Index] = i.[name]
, i.*
FROM sys.indexes i
INNER JOIN sys.tables t
ON t.[object_id] = i.[object_id]
Martin has the right answer to index you find with the NULL name.

How do you truncate all tables except lookup tables in a database using TSQL?

What is the best way to remove all the data from all the tables except look-up tables data using TSQL in SQL Server 2012 and downwards?
I would like the TSQL identify and exclude look-up tables then create truncate table statements for the other tables.
** There is almost a similar question but it truncates all the tables.
Both Lookup Tables and non Lookup tables are similar in technical characteristics. Only functionally they are different. Hence there won't be specific criteria to differentiate both of them.
Unless you set yourself up to be able to do this from the design standpoint, e.g. putting all "Lookup" tables in a "lkup" schema, or something of that nature, I don't think there's a way to do this. As someone already mentioned, a lookup table is a table like any other.
I would automate using DELETE by deleting in the right order first of all (dependencies)
1) pass the table name
2) disable your foreign keys
3) empty DELETE ALL the table
4) re-enable they keys.
this way you can control passing the table names you want "truncated" with a conditional.
or will it matter then:
ALTER PROCEDURE
up_ResetEntireDatabase
#IncludeIdentReseed BIT,
#IncludeDataReseed BIT
AS
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
IF #IncludeIdentReseed = 1
BEGIN
EXEC sp_MSForEachTable 'DBCC CHECKIDENT (''?'' , RESEED, 1)'
END
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
IF #IncludeDataReseed = 1
BEGIN
-- Populate Core Data Table Here
END
GO
And then once ready the execution is really simple:
EXEC up_ResetEntireDatabase 1, 1
I'm not sure if you mean lookup tables like one that could drive this.
build a simple table that has names of each of the database tables and create columns you could modify if necessary before you execute the script.
the columns could just be flags that tell the script whether or not to truncate that table or other.
that way you (script) will know dependencies as it reads table names. an index is not needed if you keep table order static in record number order.
just another maintenance script.
So you want to truncate the tables that have foreign keys but keep the references tables alone. This should do it.
WITH CTE_fks
AS
(
SELECT obj.name AS FK_NAME,
sch1.name AS [table_schema],
tab1.name AS [table_name],
col1.name AS [column],
sch2.name AS [ref_table_schema],
tab2.name AS [referenced_table],
col2.name AS [referenced_column]
FROM sys.objects obj
INNER JOIN sys.foreign_key_columns fkc
ON obj.object_id = fkc.constraint_object_id
INNER JOIN sys.tables tab1
ON tab1.object_id = fkc.parent_object_id
INNER JOIN sys.schemas sch1
ON tab1.schema_id = sch1.schema_id
INNER JOIN sys.columns col1
ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
INNER JOIN sys.tables tab2
ON tab2.object_id = fkc.referenced_object_id
INNER JOIN sys.schemas sch2
ON tab2.schema_id = sch2.schema_id
INNER JOIN sys.columns col2
ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
)
SELECT 'TRUNCATE TABLE ' + QUOTENAME(A.TABLE_SCHEMA) + '.' + QUOTENAME(A.table_name) + ';'
FROM INFORMATION_SCHEMA.TABLES A
LEFT JOIN CTE_fks B
ON A.TABLE_NAME = B.referenced_table
AND A.TABLE_SCHEMA = B.ref_table_schema
WHERE A.TABLE_TYPE = 'BASE TABLE'
AND A.TABLE_NAME != 'sysdiagrams'
AND B.table_name IS NULL

Resources