How to discover to which table\field is linked the foreign key of a table? - sql

I am pretty new in Microsoft SQL server and I am not much into databases.
I have the following doubt:
On my database I have a table named CPE
This table have a field (a column) named SourceId that is the FOREIGN KEY of my table.
So I think that this field have to contain the value definied in some field of another table because it binds together 2 tables).
What have I to do to discover what is the other field and the other table which is linked to?
Tnx
Andrea

You are looking for certainly:
sp_help [table_name]
or try this query:
select t.name as ForeignKeytable, fk.constraint_column_id as ForeignKey_No, c.name as ForeignKeyColumn
from sys.foreign_key_columns as fk
inner join sys.tables as t on fk.parent_object_id = t.object_id
inner join sys.columns as c on fk.parent_object_id = c.object_id and fk.parent_column_id = c.column_id
where fk.referenced_object_id = (select object_id from sys.tables where name = 'name')
order by ForeignKeytable, ForeignKey_No

Try this
Method 1 :
SELECT
object_name(parent_object_id) ParentTableName,
object_name(referenced_object_id) RefTableName,
name
FROM sys.foreign_keys
WHERE parent_object_id = object_id('Tablename')
Or:
Method 2 :
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) = 'Tablename'

In Object Explorer, right-click the table that will be on the foreign-key side of the relationship and click Design.
The table opens in Table Designer.
From the Table Designer menu, click Relationships.
The relationship appears in the Selected Relationship list with a system-provided name in the format FK__, where tablename is the name of the foreign key table.
Click the relationship in the Selected Relationship list.
Click Tables and Columns Specification in the grid to the right and click the ellipses (…) to the right of the property.
Now, you will be able to see relationship of that table with other tables.

Related

Get all Column Names being referenced in one particular Table only

I have 1000+ tables, SPs, and Views in my database.
How do I get a list of all "Column Names" across whole database that are being referenced in one particular table only; and not in any other tables or SPs or Views in my database?
i.e. I have Database A. which has Tables: B, C, D; Views: E, F, G; and SPs: H, I, J. Table B has 500 columns; and for example 250 columns are being referenced in other Views or SPs but 250 are not being used anywhere else. How do I get the list of Columns Names that are being used in Database B only and not anywhere else?
This is an interesting question. This will show you all fields in all tables.
SELECT T.name AS Table_Name ,
C.name AS Column_Name ,
P.name AS Data_Type ,
P.max_length AS Size ,
CAST(P.precision AS VARCHAR) + '/' + CAST(P.scale AS VARCHAR) AS Precision_Scale
FROM sys.objects AS T
JOIN sys.columns AS C ON T.object_id = C.object_id
JOIN sys.types AS P ON C.system_type_id = P.system_type_id
WHERE T.type_desc = 'USER_TABLE';
This will show you all field names in a specific view.
SELECT *
FROM sys.views
SELECT *
FROM sys.columns
WHERE object_id = OBJECT_ID('dbo.View_1')
Can you start with that? Post back if you have additional questions.

SQL to find the number of rows per table in a database

My goal is to create a spreadsheet of all the tables in the current database that will display the table name and the number of rows in each table. A bonus would be to also be able to display when anything was last entered or changed in the table. I'm not sure if the last part is possible though.
This is what I have so far... its nothing much but I just can't beat my head around how to add the per table row count to it.
SELECT name, type, type_desc
FROM [scheme].sys.all_objects
WHERE type = 'U'
You can use this query against the system catalog views:
SELECT
t.NAME AS TableName,
p.rows AS RowCounts
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
WHERE
t.NAME NOT LIKE 'dt%'
AND t.is_ms_shipped = 0
AND i.OBJECT_ID > 255
GROUP BY
t.Name, p.Rows
ORDER BY
t.Name
to get the desired result - all tables in the current database, and the number of rows in each.
CREATE TABLE #T
(TABLENAME VARCHAR(100) ,
COUNT INT)
INSERT INTO #T
EXEC SP_MSFOREACHTABLE 'SELECT ''?'' ,COUNT(*) FROM ?'
SELECT * FROM #T
DROP TABLE #T

How to get list of tables without any active triggers?

I have database in SQL Server 2008 with triggers on almost every table. I need to review tables without active triggers.
How to get list of all tables without any active triggers (tables without any triggers or those tables where all triggers are disabled)?
You can anti semi join between sys.tables and sys.triggers.
e.g. with NOT IN
SELECT *
FROM sys.tables
WHERE object_id NOT IN (SELECT parent_id
FROM sys.triggers
WHERE is_disabled = 0)
Or NOT EXISTS
SELECT *
FROM sys.tables t
WHERE NOT EXISTS (SELECT *
FROM sys.triggers tr
WHERE is_disabled = 0
AND tr.parent_id = t.object_id)
Neither sys.tables.object_id or sys.triggers.parent_id are nullable and in this case both give the same semantics and plan.

Calculate the maximum storage size of table record?

Is there a way to determine what the maximum size of a record would be in SQL Server past doing it by hand? For example:
CREATE TABLE test (
id INT PRIMARY KEY IDENTITY(1, 1),
name VARCHAR(256),
test_date DATETIME
)
so, if I'm not mistaken, when calculating that by hand that record could be a maximum of 272 bytes. However, I have a table with a lot more columns than that, and I need to do this for more than one table, so I wanted to know if I could do this with a simple query.
I can't find any information in INFORMATION_SCHEMA.TABLES or even INFORMATION_SCHEMA.COLUMNS where I figured I could do a simple SUM for example. Further, sysobjects and syscolumns don't seem to have the necessary information. The syscolumns table does have a length field but that's not the actual storage size.
Thanks all!
Try this:
Select schema_name(T.schema_id) As SchemaName,
T.Name As TableName,
Sum(C.max_length) As RowSize
From sys.tables T
Inner Join sys.columns C
ON T.object_id = C.Object_ID
INNER JOIN sys.types S
On C.system_type_id = S.system_type_Id
Group By schema_name(T.schema_id),
T.Name
Order By schema_name(T.schema_id),
T.Name

How to display null if a field's where condition is not met

I've got the following SQL code which returns the tables in my database, along with the primary key field in each table.
SELECT Keys.TABLE_NAME As 'Table Name',
Keys.COLUMN_NAME AS 'Primary Key'
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS Constraints
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS Keys
ON Constraints.TABLE_NAME = Keys.TABLE_NAME
AND Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME
WHERE Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY'
As it is, it only displays those tables which have a primary key. How can I modify the sql to display all tables, and those tables which do not have a primary key will display "null" in the "Primary Key" column instead?
To do this, you need to start with a list of all tables, and then join the tables using a left outer join:
SELECT t.TABLE_NAME As 'Table Name',
Keys.COLUMN_NAME AS 'Primary Key'
FROM INFORMATION_SCHEMA.TABLES t left outer join
INFORMATION_SCHEMA.TABLE_CONSTRAINTS Constraints
on t.TABLE_NAME = Constraints.Table_name and
t.Table_Schema = Constraints.Table_Schema left outer join
INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS Keys
ON Constraints.TABLE_NAME = Keys.TABLE_NAME and
Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME and
Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY'
By default a "join" is an inner join, which will only display a row if there is a corresponding row in the other table based on the join conditions. So, you will not want to use a straight join here, you need either a left join, right join, or full join which permit a table to return rows without a match.
But here you can't just switch to a left join because the table_constraints only lists ones that have constraints and also your where contraint will filter out rows that don't have a Primary Key.
So, you can bring in information_schema.tables to include every table and then move the primary key condition to the join conditions instead of the where clause. It could look something like:
SELECT t.TABLE_NAME As 'Table Name',
Keys.COLUMN_NAME AS 'Primary Key'
FROM
INFORMATION_SCHEMA.TABLES as t
left join
INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS Constraints
on t.TABLE_NAME = constraints.TABLE_NAME and t.TABLE_SCHEMA = constraints.TABLE_SCHEMA
left JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS Keys
ON Constraints.TABLE_NAME = Keys.TABLE_NAME
AND Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME
and Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY'