How to get column metadata from a table synonym - sql

How can I determine column metadata from a table synonym in a SQL Server 2005 database? I have a synonym called 'ProjectSyn' for a table called 'Project', but I can find no column metadata for the synonym.
My guess is to somewhere determine the 'base table' for the synonym, then query for column metadata for that table. Is this a correct approach, and if not, what would be?

This is my solution which works with synonyms of different databases:
SELECT TOP 0 * INTO #TEMP1 FROM YourTable
SELECT
[column_name] = c.name,
[data_type] = t.name,
[character_maximum_length] = c.max_length
FROM tempdb.sys.columns c
inner join tempdb.sys.types t on t.system_type_id = c.system_type_id
WHERE [object_id] = object_id('tempdb..#TEMP1');
DROP TABLE #TEMP1

Something like this? (edited)
select c.*
from
sys.columns c
inner join sys.synonyms s on c.object_id = object_id(s.base_object_name)
where
s.name = 'ProjectSyn'

Yes, I think getting the base object and then retrieve the columns, is your only option.
To get the base object name for a synonym, just query the view sys.synonyms

Related

How to determine if sql table is Temporal?

With SQL Server 2016 supporting Temporal Tables I wonder if there is a way to determine if a table is currently temporal? Something like
select * from sys.objects where object_id('dbo.MyTable', 'u') = parent_object_id and type_desc = "SYSTEM_VERSIONED"
SELECT temporal_type
FROM sys.tables
WHERE object_id = OBJECT_ID('dbo.MyTable', 'u')
0 = NON_TEMPORAL_TABLE
1 = HISTORY_TABLE
2 = SYSTEM_VERSIONED_TEMPORAL_TABLE
Documentation
Another way of listing temporal tables with their history tables together is given in this SQL tutorial as List Temporal and History Tables in a SQL Server Database
select
t.object_id,
t.name,
t.temporal_type,
t.temporal_type_desc,
h.object_id,
h.name,
h.temporal_type,
h.temporal_type_desc
from sys.tables t
inner join sys.tables h on t.history_table_id = h.object_id
Here is a simple answer to the original basic question:
SELECT *
FROM sys.tables
WHERE name = 'MyTable'
AND schema_id = SCHEMA_ID('dbo')
AND temporal_type_desc = 'SYSTEM_VERSIONED_TEMPORAL_TABLE'
And here is a similar query looking for the actual system managed history table:
SELECT h.* FROM sys.tables p
INNER JOIN sys.tables h
ON p.history_table_id = h.object_id
WHERE p.name = 'MyTable'
AND p.schema_id = SCHEMA_ID('dbo')
AND p.temporal_type_desc = 'SYSTEM_VERSIONED_TEMPORAL_TABLE';
This query will give you the system versioned tables, the associated history tables, the retention policy, and whether the retention policy is enabled at the database level.
From Microsoft Docs
SELECT DB.is_temporal_history_retention_enabled,
SCHEMA_NAME(T1.schema_id) AS TemporalTableSchema,
T1.name as TemporalTableName, SCHEMA_NAME(T2.schema_id) AS HistoryTableSchema,
T2.name as HistoryTableName,T1.history_retention_period,
T1.history_retention_period_unit_desc
FROM sys.tables T1
OUTER APPLY (select is_temporal_history_retention_enabled from sys.databases
where name = DB_NAME()) AS DB
LEFT JOIN sys.tables T2
ON T1.history_table_id = T2.object_id WHERE T1.temporal_type = 2

Getting the decriptions of the tables and columns via a sql statement

I have a database and a lot of tables inside it. I wrote some information into the each table and column's decription part. And now using query i want to see all table and columns descriptions.
Note: DATABASE -> ms sql server
Can you please help me ?
You can see that using INFORMATION_SCHEMA
To get columns for each table you can do:
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
To get table information you can do:
SELECT * FROM INFORMATION_SCHEMA.TABLES
Check this query:
SELECT
t.name AS TableName
, td.value AS TableDescription
, c.name AS ColumnName
, cd.value AS ColumnDescription
FROM sys.tables t
INNER JOIN sys.columns c ON t.object_id = c.object_id
LEFT JOIN sys.extended_properties td
ON td.major_id = t.object_id
AND td.minor_id = 0
AND td.name = 'MS_Description'
LEFT JOIN sys.extended_properties cd
ON cd.major_id = t.object_id
AND cd.minor_id = c.column_id
AND cd.name = 'MS_Description'
select * from INFORMATION_SCHEMA.TABLES
select * from INFORMATION_SCHEMA.COLUMNS
select * from user_col_comments;
This will display all tables's column with comments for the logged in user.
select * from user_col_comments where table_name = '<table name>';
This will display specified tables's column with comments for the logged in user.
desc table_name query is used to describe the table

Getting Objects information

I am trying to get the table and column information. So I wrote two queries like this:
SELECT * FROM Chag.sys.columns c
WHERE OBJECT_NAME(c.object_id)='Aduser'
SELECT * FROM Chag.sys.tables so
WHERE so.name = 'Aduser' AND SCHEMA_NAME(so.schema_id) = 'Tref'
These two work fine when I execute them in Chag Database but when I execute this in different databse they return nothig.
I want to execute them in different database so how do i do that?
The OBJECT_NAME() function accepts an additional parameter of database ID. As for SCHEMA_NAME(), you should probably replace it with OBJECT_SCHEMA_NAME(), which is equivalent to SCHEMA_NAME(), only it uses the object ID instead of schema ID and accepts the database ID too as the second (optional) parameter.
You can use DB_ID() to get the ID of the specified database.
Here are modified versions of your statements:
SELECT *
FROM Chag.sys.columns c
WHERE OBJECT_NAME(c.object_id, DB_ID('Chag'))='Aduser'
SELECT *
FROM Chag.sys.tables so
WHERE so.name = 'Aduser'
AND OBJECT_SCHEMA_NAME(so.object_id, DB_ID('Chag')) = 'Tref'
If the reason is in functions OBJECT_NAME, SCHEMA_NAME like Shark pointed out, then getting data from corresponding views instead of calling those functions may help:
select c.* from chag.sys.columns c
join chag.sys.objects o on
c.object_id = o.object_id
where o.name = 'Aduser'
select t.* from chag.sys.tables t
join chag.sys.schemas s on
t.schema_id = s.schema_id
where t.name = 'Aduser' and s.name = 'Tref'
Because you are using a Database.Schema.Object reference. Try running this against other databases:
SELECT * FROM sys.columns c
WHERE OBJECT_NAME(c.object_id)='Aduser'
SELECT * FROM sys.tables so
WHERE so.name = 'Aduser' AND SCHEMA_NAME(so.schema_id) = 'Tref'
Notice, though, that if there is no 'Aduser' or 'Tref' objects then you will not get results.

A query to determine if a column is computed [duplicate]

Would any of you know how to get the list of computed columns in a SQL Server database table?
I found sys.sp_help tablename does return this information, but only in the second result-set.
I am trying to find out if there is a better way of doing this. Something which only returns a single result set.
Check the sys.columns system catalog view:
SELECT *
FROM sys.columns
WHERE is_computed = 1
This gives you all computed columns in this database.
If you want those for just a single table, use this query:
SELECT *
FROM sys.columns
WHERE is_computed = 1
AND object_id = OBJECT_ID('YourTableName')
This works on SQL Server 2005 and up.
UPDATE: There's even a sys.computed_columns system catalog view which also contains the definition (expression) of the computed column - just in case that might be needed some time.
SELECT *
FROM sys.computed_columns
WHERE object_id = OBJECT_ID('YourTableName')
If you want to use the INFORMATION_SCHEMA views, then try
SELECT
COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME),COLUMN_NAME,'IsComputed')
AS IS_COMPUTED,
*
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME='<Insert Your Table Name Here>'
For SQL Server 2000 the syntax is:
SELECT * FROM sys.columns
WHERE is_computed = 1
And the slightly more useful:
SELECT
sysobjects.name AS TableName,
syscolumns.name AS ColumnName
FROM syscolumns
INNER JOIN sysobjects
ON syscolumns.id = sysobjects.id
AND sysobjects.xtype = 'U' --User Tables
WHERE syscolumns.iscomputed = 1
sample output:
TableName ColumnName
===================== ==========
BrinksShipmentDetails Total
AdjustmentDetails Total
SoftCountDropDetails Total
CloserDetails Total
OpenerDetails Total
TransferDetails Total
(6 row(s) affected)
If you have many tables with computed columns and want to see the table names as well:
SELECT sys.objects.name, sys.computed_columns.name
from sys.computed_columns
inner join sys.objects on sys.objects.object_id = sys.computed_columns.object_id
order by sys.objects.name

Get List of Computed Columns in Database Table (SQL Server)

Would any of you know how to get the list of computed columns in a SQL Server database table?
I found sys.sp_help tablename does return this information, but only in the second result-set.
I am trying to find out if there is a better way of doing this. Something which only returns a single result set.
Check the sys.columns system catalog view:
SELECT *
FROM sys.columns
WHERE is_computed = 1
This gives you all computed columns in this database.
If you want those for just a single table, use this query:
SELECT *
FROM sys.columns
WHERE is_computed = 1
AND object_id = OBJECT_ID('YourTableName')
This works on SQL Server 2005 and up.
UPDATE: There's even a sys.computed_columns system catalog view which also contains the definition (expression) of the computed column - just in case that might be needed some time.
SELECT *
FROM sys.computed_columns
WHERE object_id = OBJECT_ID('YourTableName')
If you want to use the INFORMATION_SCHEMA views, then try
SELECT
COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME),COLUMN_NAME,'IsComputed')
AS IS_COMPUTED,
*
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME='<Insert Your Table Name Here>'
For SQL Server 2000 the syntax is:
SELECT * FROM sys.columns
WHERE is_computed = 1
And the slightly more useful:
SELECT
sysobjects.name AS TableName,
syscolumns.name AS ColumnName
FROM syscolumns
INNER JOIN sysobjects
ON syscolumns.id = sysobjects.id
AND sysobjects.xtype = 'U' --User Tables
WHERE syscolumns.iscomputed = 1
sample output:
TableName ColumnName
===================== ==========
BrinksShipmentDetails Total
AdjustmentDetails Total
SoftCountDropDetails Total
CloserDetails Total
OpenerDetails Total
TransferDetails Total
(6 row(s) affected)
If you have many tables with computed columns and want to see the table names as well:
SELECT sys.objects.name, sys.computed_columns.name
from sys.computed_columns
inner join sys.objects on sys.objects.object_id = sys.computed_columns.object_id
order by sys.objects.name