sys.columns shows details but table missing from sys.tables - sql

I was wanting to know in which table in the database a certain column exists. So I used the sys.columns with a where condition, and this gave me some object_id.
select * from sys.columns where name like 'mycol%'
Next I went about finding the actual name of this table from the object_id received from the above query, as follows from sys.tables. But my select statement returns an empty result. Does this mean such a table does not exist in the database. If so, how is sys.columns telling me that the column I'm looking for lies in a table with this object_id?
select * from sys.tables where object_id='584895884'
I'm using Microsoft SQL Server 2014.

It means that it is not a table, but either a View, or a Table-Valued Function, or one of several other types of objects. Use this instead:
SELECT *
FROM sys.objects
WHERE [object_id] = 584895884;
Please note that the [object_id] field is a number, not a string, so shouldn't be quoted.
You can also do this in a single query:
SELECT *
FROM sys.columns sc
INNER JOIN sys.objects so
ON so.[object_id] = sc.[object_id]
WHERE sc.name LIKE N'mycol%';
The type and type_desc fields from sys.objects will indicate what type of object the column is found in. The possibilities I see in one of my databases are:
type_desc (type)
CLR_TABLE_VALUED_FUNCTION (FT)
INTERNAL_TABLE (IT)
SQL_INLINE_TABLE_VALUED_FUNCTION (IF)
SQL_TABLE_VALUED_FUNCTION (TF)
SYSTEM_TABLE (S)
TYPE_TABLE (TT)
USER_TABLE (U)
VIEW (V)
The sys.tables system view will only contain objects of type U / USER_TABLE.

Related

How to count specific column name in all tables of one SQL Server Database object

I want to count tables that have a specific column name. For instance, dbo.Management has 300 tables. Some tables have ProtectionKey column, and others don't.
I need a list of all the tables that have that column ProtectionKey, or at least a count of them.
I have looked into similar examples but those are either counting ALL columns in a DB or ALL columns in one table.
I would personally use the sys objects for this, as INFORMATION_SCHEMA can return incorrect information:
SELECT s.[name] AS SchemaName,
t.[name] AS TableName
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
WHERE c.[name] = N'ProtectionKey';
Use INFORMATION_SCHEMA.COLUMNS:
select c.*
from INFORMATION_SCHEMA.COLUMNS c
where column_name = 'ProtectionKey';
This has many columns. The ones you want are TABLE_NAME and TABLE_SCHEMA.
Also, this only works in one database at a time, so you need to run it in each database where you want to search for the tables.

Use field values inside a Where statement

I'm currently developing some Quality Checks for a database and we have a table that lists out which columns are Required fields. My question is, would it be possible to use this table to generate a where...is null statement? Example below
select * from Required_Fields_Table
inner join Transaction_Table
on key fields
where (value inside field) is null
Thanks!
edit: this is using Microsoft SQL Server
More Details:
We have a Transactions table, and whether a field in that table is required is different based on the type of user (new, active, pending, etc). We have a table that maps these requirements out (a record for each field/status combination). I was hoping to use that table to run a check to make sure we weren't missing required information.
I'm not sure if I understand your question, but hopefully this will heap... you can use this query to get a list of tables and all fields that are nullable
select o.name TableName, c.name ColumnName
from sys.objects o
inner join sys.columns c on o.object_id = c.object_id
where c.is_nullable = 1 -- 1 for nullable, 0 for not nullable
and o.type = 'u' -- user table
and o.name = '{insert table name here if you wish to refine your search}'
From there you can build up queries for each table with the help of a cursor

Command to distinguish a table from a view

Is there a command to determine whether a given relation is a table or a view?
The trial-and-error method I'm using is to do:
SHOW CREATE VIEW table_name
If it's a table, not a view, my database software (Presto in DBeaver) will give me an error:
Relation table_name is a table, not a view
I presume this error is coming from a similar command being run internally to vet my query. If it's a view, the command of course works.
The following will show a table of information about all tables available, including which are views and which are tables:
SELECT * FROM information_schema.tables
See Information Schema for more details.
In SQL Server, you can use column 'Type' in Sys.Objects to differentiate a Table or View. If value in column Type is 'V' then its a View, otherwise if value in column Type is 'U' then its a table
To check if it is a table use below query
SELECT DISTINCT NAME, O.TYPE FROM SYS.OBJECTS O WHERE O.NAME LIKE 'Prefix%' AND O.TYPE='U'
To check if it is a view use below query
SELECT DISTINCT NAME, O.TYPE FROM SYS.OBJECTS O WHERE O.NAME LIKE 'Prefix%' AND O.TYPE='V'

How to update column name after finding the table names from information schema

I have run a script to find the table names with a specific column name from a database using the information schema
here is the query
use IMS_SCMS_DIGITAL_POWER
select * from information_schema.columns
where column_name like 'COMPANY_ID%'
after finding the table names now i would like to update the specific column values of all the database. Need solutions.
Run following query to get all tablenames with specific column name
SELECT t.name AS TableName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE '%COMPANY_ID%'
just use in forward only cursor with tablenames to update the specific table.

Copy Column Into Existing Table using SQL

I want to create a column in databaseA with the same name, type, length and precision as another column in databaseB.
I need something like this:
INSERT INTO dbo.databaseA(col_name)
SELECT col_name
FROM dbo.databaseB;
GO
But the *col_name* does not yet exist in databaseA. I want to create it with the same type as *col_name* in databaseB.
I've also looked at:
ALTER TABLE table_name ADD col_name data_type
INSERT INTO dbo.databaseA(col_name)
SELECT col_name
FROM dbo.databaseB;
GO
But I don't know the data_type of the column I need to copy.
Edit:
** I'm using SQL Server 2008 R2 **
You can retrieve the datatype of the column from the database by querying the system views, similar to the following:
SELECT c.*, s.name
FROM sys.columns c
INNER JOIN sys.objects o
ON c.object_id = o.object_id
INNER JOIN sys.types s
ON c.user_type_id = s.user_type_id
WHERE o.name = 'B'
AND c.name = 'ColumnName'
You'll need to connect to DatabaseB, replace o.name = 'B' with your table's name and replace c.Name = 'ColumnName' with your column's name.
Once you have the datatype you would need to construct a DDL statement to add the column to the table in database A, something along the lines of the following:
ALTER TABLE dbo.MyTableName ADD MyColumnName DATA_TYPE_HERE
Once the table has been updated you can construct and execute your insert statement:
INSERT INTO DatabaseA.dbo.MyTableName (column list)
SELECT (column list)
FROM DatabaseB.dbo.MyTableName
Note that the above assumes both databases are located on the same SQL Server Instance and they both reside in the dbo schema.
If this is something you plan on using in the future you should add some defensive programming steps to make sure you only add the column if the column doesn't already exist in the table.