Command to distinguish a table from a view - sql

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'

Related

Find all views containing specific table names

I have several views in my database that are built on tables.
Is it possible to query for view names which contain specific tables in it?
For example by using:
Where tablename like '%TableA%'
I tried
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE '%TableA%'
But this gives list of tables created using this table.
Use the following query to search views for a table:
SELECT Objects.name, Modules.definition
FROM sys.sql_modules AS Modules INNER JOIN sys.objects AS Objects ON
Modules.object_id = Objects.object_id
WHERE definition like '%TableA%'

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

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

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.

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.

Transact SQL - View Data Type Schronization Question

I working on an auto synchronization project where I want to get the data types from a View on SQL Server 2008 R2 and compare it to a table in the same database. I am familiar with syscolumns, However, this only appears to work with tables, not Views. Any suggestions or references would be greatly appreciated.
Essentially, if View_A has a new column added to it, I need to add the column to Table_A with the same properties as View_A so that all data types, lengths, and fields on Table_A are always the same as View_A.
Thanks
I'm not sure about syscolumns only showing columns of base tables, but you can use this query:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourView'
sys.columns includes column information for views:
CREATE VIEW dbo.Test_View
AS
SELECT * FROM sys.objects
SELECT *
FROM sys.columns
WHERE object_id = OBJECT_ID('dbo.Test_View')
The columns in sys.columns are for both views and tables.
So, you should be able to do the same as a table, i.e.
SELECT *
FROM sys.columns
WHERE object_id = OBJECT_ID('MyViewName')