Get only table columns with DbConnection.GetSchema method - sql-server-2005

With C# and SQL Server 2005 and by using DbConnection.GetSchema() method, I want to get all a table's columns (not of views) only. I have found two collection names related to this
Columns that returns table and views' columns
ViewColumns returns all the view's columns
Neither of above two returns table columns only, nor they have any property to filter Table-columns.
Any help is respected.

I don't see any easy way to do this with this particular API you're trying to achieve this with - but why not just use a query like this to get your information?
SELECT
c.name AS 'ColumName',
ty.Name AS 'TypeName',
c.max_length,
c.is_identity,
c.is_nullable,
t.name AS 'TableName'
FROM sys.columns c
INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id
INNER JOIN sys.tables t ON c.object_id = t.object_id
Just load that into a SqlCommand and execute it against the open connection you have and read the result into some DataTable or other structure for your use. This gives you only table columns - and all of them.

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.

Getting column information from system MS SQL Server

When I am using the below SQL statement to retrieve the column information of a SQL Server database. I am getting more columns than there actually are I presume this is because of the system columns that are there also.
SELECT
c.name Field,
t.name Type,
c.Precision,
c.Scale,
c.max_length,
c.is_nullable,
c.collation_name
FROM
sys.columns c
INNER JOIN
sys.types t ON t.system_type_id = c.system_type_id
WHERE
object_id = OBJECT_ID('SOPOrders')
You will see the above query is producing ten Order Memos when in fact their should only be the one the var char I still want to be able to report back the prevision dataype maxlength and the null able factor so what is wrong with the above query please.
There may be a couple of reasons for that. First of all, you are joining types by wrong condition - you should use user_type_id instead of system_type_id on both sides. The latter gives you the underlying built-in type which was used as a basis of a user-defined one. See this query, for example:
select * from sys.types t where t.user_type_id != t.system_type_id;
Another possible thing is that the table has a sparse column set, but I might be wrong here.
And, of course, make sure you are actually querying the information about the right table - always include the schema name qualifier, along with the object name, such as:
WHERE object_id=object_id('dbo.SOPOrders')
Failure to do so will not result in duplication you observe, but following it will save you a lot of time trying to figure out the cause of intermittent inconsistencies, when you will have objects with the same name in different schemas.
Why not using Information_Schema.COLUMNS instead??
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'SOPOrders'
Or try to join on
ON c.user_type_id = t.user_type_id
instead of
ON t.system_type_id=c.system_type_id

Query a view to get its column names

I have a large number of SQL 2008 R2 views. I would like to know which database fields are referenced in the views.
Is there a way that I can query the schema to list out these column names?
Use this query against sys.sql_dependencies.
SELECT
ViewName = O.name,
ReferencedTableName = X.name,
ReferencedColumnName = C.name,
T.is_selected,
T.is_updated,
T.is_select_all,
ColumnType = M.name,
M.max_length,
M.precision,
M.scale
FROM
sys.sql_dependencies AS T
INNER JOIN sys.objects AS O ON T.object_id = O.object_id
INNER JOIN sys.objects AS X ON T.referenced_major_id = X.object_id
INNER JOIN sys.columns AS C ON
C.object_id = X.object_id AND
C.column_id = T.referenced_minor_id
INNER JOIN sys.types AS M ON
M.system_type_id = C.system_type_id AND
M.user_type_id = C.user_type_id
WHERE
O.type = 'V'
ORDER BY
O.name,
X.name,
C.name
You can look at the view definition and see the referenced tables there. For that you can simply use sp_helptext like so:
sp_helptext 'vStores'
You can retrieve the view defintion from the metatdata in 'sys.objects', see also this answer:
Is there a way to retrieve the view definition from a SQL Server using plain ADO?
That won't give you the underlying tables directly, though.
SQL Server does this trick itself when you define an object as having Schema Binding: when any objects are changed that are referenced by other objects using schema binding, that change is stopped and an error is given. Perhaps you can look into how SQL Server keeps track of those references to see what columns are used in a view. More on Schema binding here: https://www.mssqltips.com/sqlservertip/4673/benefits-of-schemabinding-in-sql-server/

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

Read data from tables returned from inner query

So, I am working on a project where I need to find all tables that have the column xyz, and then remove all rows from such tables if the updated_at date for that row from that table is older than some duration.
I got the list of all tables from SQL Server like this:
SELECT
t.name AS table_name
FROM
sys.tables AS t
INNER JOIN
sys.columns c ON t.object_id = c.object_id
WHERE
c.name = 'xyz';
Now I want to use each of the tables returned from this query to DELETE all rows from these tables which satisfy some criteria. Can someone help me with the 'Nested query' please?
What you're contemplating isn't going to work; you need to explicitly specify which table you are deleting from in a delete statement.
My approach would be to use your query to dynamically generate the delete statements, then save the output of your query in a file, and run the file. This also gives you a chance to review and double-check the deletes before you run them, which is a good idea when you're making large-scale data changes like these.
select
'delete from ' + t.name + ' where updated_at <= ''2013-01-01'';'
from
sys.tables t
where
exists (select null from sys.columns c where c.object_id = t.object_id and c.name = 'xyz')
http://sqlfiddle.com/#!3/475c0/2