Find tables for which specific column not exists sql server - sql-server

How to find tables in which specific column not exists.
E.g column ID not present in table Contact, then Contact table will be in result set.
I tried:
SELECT DISTINCT t.name
FROM sys.tables t
INNER join sys.columns C ON c.object_id = t.object_id
WHERE c.name <> 'ID'
But above query return all table for which column ID is present in it.

Can u try this query,
SELECT * FROM sys.tables WHERE type = 'U' AND object_id NOT IN (
SELECT DISTINCT c.object_id FROM sys.columns c WHERE c.name = 'ID')

SELECT name
FROM sys.Tables
WHERE Object_ID NOT IN (SELECT Object_ID FROM sys.Columns WHERE name = 'ID')

You don't need to perform a join, you can just add a subquery that identifies tables that have an ID column and exclude the object_id's using NOT IN(..the subquery..):
SELECT DISTINCT t.name
FROM sys.tables t
WHERE t.object_id NOT IN (SELECT object_id FROM sys.columns WHERE name = 'id')
The reason your query doesn't work is because you are simply getting all columns that aren't = ID and each table has many columns that match that criteria so they will be returned even if there is an ID column.

One method is with NOT EXISTS:
SELECT OBJECT_SCHEMA_NAME(t.object_id) AS SchemaName
, t.name AS TableName
FROM sys.tables t
WHERE NOT EXISTS ( SELECT *
FROM sys.columns c
WHERE c.object_id = t.object_id
AND c.name = 'ID' );

Try the following, lists all table names NOT having ID.
SELECT tableName
FROM (
SELECT DISTINCT
t.name AS tableName
,c.name AS columnName
FROM sys.tables t
INNER JOIN sys.columns C
ON c.object_id = t.object_id
) AS t
WHERE columnName NOT IN( 'ID')
GROUP BY tableName

If you down't want to see system tables, then..
SELECT DISTINCT OBJECT_NAME(OBJECT_ID) TableName FROM SYS.COLUMNS WHERE NAME <> 'id'
and OBJECTPROPERTY (OBJECT_ID, 'IsUserTable') = 1
EXCEPT
SELECT DISTINCT OBJECT_NAME(OBJECT_ID) TableName FROM SYS.COLUMNS WHERE NAME = 'id'

Related

System Versioned Table check schema from sys.tables

How to check if a table has versioning enabled by specifying not only the table name but also the schema.
I use:
IF EXISTS (SELECT 1 FROM sys.tables
WHERE NAME = 'tablename'
AND temporal_type = 2)
SELECT 1 AS TABLE_EXIST
ELSE
SELECT 0 AS TABLE_EXIST
Regards
You can JOIN sys.schemas and filter on the name column from both tables:
IF EXISTS (
SELECT 1
FROM sys.tables t
INNER JOIN sys.schemas s ON s.schema_id = t.schema_id
WHERE temporal_type = 2
AND s.name = 'schemaname'
AND t.name = 'tablename'
)
SELECT 1 AS TABLE_EXIST
ELSE
SELECT 0 AS TABLE_EXIST;
You can use the SCHEMA_ID function, which exists to simplify queries like this:
SELECT *
FROM SYS.tables
WHERE
NAME = 'tablename'
and schema_id = schema_id('dbo')
and temporal_type = 2

How to get column-wise constraints in SQL Server

I am using below query to get constraints on required table:
SELECT
OBJECT_NAME(o.object_id) AS ConstraintName,
SCHEMA_NAME(schema_id) AS SchemaName,
OBJECT_NAME(parent_object_id) AS TableName,
type_desc AS ConstraintType
FROM
sys.objects o
-- INNER JOIN
-- sys.columns c ON o.object_id = c.object_id
WHERE
type_desc LIKE '%CONSTRAINT'
AND OBJECT_NAME(parent_object_id)= 'All_Data_Types'
Successfully getting table-wise constraint details. But, I want column's information as well.
Could someone help me with this?
Thanks in advance
Fast solution for default constraint is
SELECT dc.object_id AS ConstraintID, DC.name AS ConstraintName
, O.object_id AS TableID, O.name AS TableName
, C.object_id AS ColumnID, C.name AS ColName
FROM sys.default_constraints AS DC
LEFT JOIN sys.objects AS O ON O.object_id = DC.parent_object_id
LEFT JOIN sys.columns c ON o.object_id = c.object_id AND DC.parent_column_id = c.column_id
For table constraints you could use something like this:
SELECT KCU.*, TC.CONSTRAINT_TYPE
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC ON TC.CONSTRAINT_SCHEMA = KCU.CONSTRAINT_SCHEMA AND TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME
If you are on SQL Server 2012 or later then you can use system view sys.sysconstraints:
Contains mappings of constraints to the objects that own the
constraints within the database.
So, this query:
SELECT *
FROM sys.sysconstraints s
INNER JOIN sys.objects o ON o.object_id = s.constid
theoretically returns the same number of rows as your query. But now you have the additional information about the ID of the column on which the constraint is defined. That is column colid of sys.sysconstraints:
ID of the column on which the constraint is defined.
0 = Table constraint
Thus, using this query:
SELECT OBJECT_NAME(o.object_id) AS ConstraintName,
SCHEMA_NAME(o.schema_id) AS SchemaName,
OBJECT_NAME(o.parent_object_id) AS TableName,
o.type_desc AS ConstraintType,
COALESCE(c.COLUMN_NAME, 'Table constraint') AS ColumnName
FROM sys.sysconstraints s
INNER JOIN sys.objects o ON o.object_id = s.constid
LEFT JOIN INFORMATION_SCHEMA.COLUMNS c ON c.ORDINAL_POSITION = s.colid AND s.colid <> 0
you also get the name the column related to the constraint.
Here is the query. You are using INNER JOIN on wrong column_name of tables.
You used this
INNER JOIN sys.columns c ON o.object_id = c.object_id
I replaced it with
INNER JOIN sys.columns c ON o.parent_object_id = c.object_id
Now you can see the column_name as well as table_name along with constraint_details.
SELECT OBJECT_NAME(o.object_id) AS ConstraintName,
SCHEMA_NAME(schema_id) AS SchemaName,
OBJECT_NAME(parent_object_id) AS TableName,
c.name as ColumnName,
type_desc AS ConstraintType
FROM sys.objects o
INNER JOIN sys.columns c ON o.parent_object_id = c.object_id
WHERE type_desc LIKE '%CONSTRAINT';
Also avoid using the below clause
AND OBJECT_NAME(parent_object_id)= 'All_Data_Types'

What are the tables whose names start with `TT_`?

Using this SQL statement to find in my database all tables the have columns whose names contain ItemId:
SELECT o.name,
c.name
FROM sys.columns c
INNER JOIN sys.objects o ON c.object_id = o.object_id
WHERE c.name LIKE '%ItemId%'
ORDER BY o.name, c.column_id
I received a result containing two tables:
ResourceData
TT_Data_117F9D94
I know about the ResourceData table and I can find it in the list of my tables.
But I have not been able to find in my database any table name TT_Data_117F9D94.
Any idea where/how did this table show up in the result of my query?
First of all
You should have used
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%itemid%';
Probably TT_Data_117F9D94 is a data table in your database.
Please check the database design of that table. Or simply do a select query from that table.
Check about table types -
CREATE TYPE dbo.TT_Type AS TABLE (a INT)
SELECT o.name, c.name
FROM sys.columns c
JOIN sys.objects o ON c.[object_id] = o.[object_id]
WHERE c.name = 'a'
Correct query -
SELECT SCHEMA_NAME(o.[schema_id]), o.name, c.name
FROM sys.columns c
JOIN sys.objects o ON c.[object_id] = o.[object_id]
WHERE o.[type] = 'U' -- only user tables

How to get table columns according its schema and table name?

I want to get ColumnName and it's datatype and is_identity for each column of different databases for specific table and schema.
I use following code but SCHEMA_NAME is for current database but I want to run this query from master or another database.
How to check schema name?
SELECT
c.name AS column_name, tp.name as data_type, c.is_identity iden
FROM
DatabaseName.sys.tables AS t
INNER JOIN
DatabaseName.sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
INNER JOIN
DatabaseName.sys.types tp ON c.user_type_id = tp.user_type_id
WHERE
t.name = 'PlaceType'
AND SCHEMA_NAME(t.schema_id) = 'Coding'
Instead of SCHEMA_NAME, use OBJECT_SCHEMA_NAME, like so:
SELECT c.name AS column_name,tp.name as data_type,c.is_identity iden FROM
DatabaseName.sys.tables AS t INNER JOIN
DatabaseName.sys.columns c ON t.OBJECT_ID = c.OBJECT_ID INNER JOIN
DatabaseName.sys.types tp ON c.user_type_id = tp.user_type_id where
t.name='PlaceType' and OBJECT_SCHEMA_NAME(t.object_id,DB_ID(Databasename))='Coding'
Just change the last condition like
and SCHEMA_NAME(t.schema_id) in (Select name from Sys.Databases where database_id > 4)

Get column information for a User-Defined Table Type

How can I get back the column information for a User-Defined Table Type?
EXEC sp_columns TABLENAME
gets me back all the column information for a table.
I want to do the same thing for a User-Defined Table Type called SearchList and roughly the same column information back.
I want to get this so I can code generate the Data Tables that I need in c#.
UPDATE TO SHOW WHAT I USED
select c.name as COLUMN_NAME, t.name as [TYPE_NAME], c.precision as [PRECISION], c.is_nullable as [NULLABLE], c.system_type_id, c.precision as [LENGTH]
from sys.columns c, sys.types t
where c.object_id = (select type_table_object_id from sys.table_types where name = 'SearchList')
and t.user_type_id = c.user_type_id
order by c.column_id
This will list all table types and their columns:
select tt.name, c.name from sys.table_types tt
inner join sys.columns c on c.object_id = tt.type_table_object_id
order by c.column_id
You can add a where clause and select other columns, as appropriate, to get what you need.
I have used below query in my project to get the table type with column name and data type.
select tt.name AS table_Type, c.name AS table_Type_col_name,st.name AS
table_Type_col_datatype
from sys.table_types tt
inner join sys.columns c on c.object_id = tt.type_table_object_id
INNER JOIN sys.systypes AS ST ON ST.xtype = c.system_type_id
order by tt.name

Resources