Locating a table in the database - sql-server

When I run the following query I get the results as expected.
select * from [Beep].[Bopp]
Then, I ran the query below to "find" the table.
select * from sys.objects
where type='U'
and name like '%Bopp%'
It finds the table and lists the row describing it. However, I can't see any reference to Beep there. The name only contains Bopp, so I'm guessing that there a key that I need to look up but I don't know which column that is nor in what table to look it up.
edit
Based on the comments, I improved the query but I'm still not sure in what table to look up the actual name of the schema. The following gives me waaay to many hits (and setting the type didn't actually give me anything Beep-like.
select * from sys.tables t
left join sys.objects s
on t.schema_id = s.schema_id
where t.name like '%Bopp%'
I checked the objects for the specific name like so.
select * from sys.objects
where name like '%Beep%'
To my surprise, I didn't see any hits at all. Where is the little Beep-y thing hiding?!

You can use the schema_name() function against the schema_id column of sys.objects, like so:
select schema_name([schema_id]) from sys.objects where [name] like '%Bopp%';
Alternatively, you can query INFORMATION_SCHEMA.TABLES, which has a TABLE_SCHEMA column that gives the name of the schema rather than its id.
select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'Bopp';

Beep is the schema name for which you should attach another sys table like so:
select sys.schemas.name as schema_name, sys.objects.name as object_name
from sys.objects
INNER JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id
where type='U'
and sys.objects.name like '%Bopp%'

Related

Combine table and views in T-SQL

I am looking into extract table name and all related views and schemas in my SQL Server.
Until now I have used this SQL code to do that:
SELECT
t.VIEW_SCHEMA,
t.VIEW_NAME,
t.TABLE_SCHEMA,
t.TABLE_NAME
FROM
INFORMATION_SCHEMA.VIEW_TABLE_USAGE t
WHERE
t.TABLE_NAME = 'MYTABLE'
AND t.VIEW_NAME like '%_something%'
The INFORMATION_SCHEMA.VIEW_TABLE_USAGE seems only to be updated when views actually are used, so when I run my code on a table with have new view definitions or a views has never been used it returns nothing.
I have tried to combine INFORMATION_SCHEMA.VIEWS and INFORMATION_SCHEMA.TABLES but I can't find a key to join on.
I have also tried to look into sys.tables and sys.views but I still haven't found a way to join it.
I really need to get the columns specified in SQL.
Any ideas on how to do that? Maybe my approach is all wrong.
SQL Server offers a few possibilities via sys.sql_expression_dependencies and sys.dm_sql_referencing_entities()
sys.sql_expression_dependencies is easier to use, an example for your purpose would be
select
Schema_Name(v.schema_id) View_Schema, v.name View_Name,
Schema_Name(t.schema_id) Table_Schema, t.name Table_Name
from sys.tables t
join sys.sql_expression_dependencies d on d.referenced_id=t.object_id
join sys.objects v on v.object_id=d.referencing_id and v.type='V'
where
t.name='tablename'
and v.name like '%something%'

Ordinal column position from sys schema

How can I get the following query, working on both views and tables, by using the SYS schema?
SELECT c.column_name,c.ordinal_position
from information_schema.columns c
where TABLE_SCHEMA='dbo'
and table_name='def_transaction_pt'
I have used the following until now, but I don't know where to get the ordinal column position from:
select *
from
sys.objects o
inner join sys.columns c on o.object_id=c.object_id
where o.name='def_transaction_pt'
You are on the right path...
DECLARE #ObjectName sysname = 'def_transaction_pt',
#SchemaName sysname = 'dbo'
SELECT c.name As Column_Name, ROW_NUMBER() OVER(ORDER BY c.column_id) As Ordinal_Position
FROM sys.columns AS c
JOIN sys.objects AS o
ON c.object_id = o.object_id
JOIN sys.schemas AS s
ON o.schema_id = s.schema_id
WHERE o.name = #ObjectName
AND s.name = #SchemaName
Note: I've only joined the sys.schemas to enable filtering using schema name,
and sys.objects to allow filtering using table/view name
After reading the comments and documentation, I've decided to adopt Larnu's suggestion about using row_number instead of the column_id directly.
Also, I've changed All_columns to Columns since it contains the columns from both tables and views.
BTW, the official documentation of information_schema.Columns describes the Ordinal_Position as "Column identification number." - which might be just the same as the Column_Id - It would require more testing to figure out that part.
BTW #2: Though you can't change the column's ordinal position using an alter table, it is possible to do using the visual designer (which in turn, drops and re-creates the table) - and if you do that, the column id for all columns is re-calculated, so it's always corresponding with the actual ordinal position (gaps aside).

How to check a database in SQL to make sure that all of its tables are in use?

I was assigned to see if all of the current tables in a database are used and if not to drop them. These are the steps I have taken so far:
Searched tables names in the program that uses that database to see if a query has been made in the program based on those tables names.
Investigated if a table primary key has been used in any other places such as view or table (Connectivity with other used tables). I used:
SELECT
t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM
sys.tables AS t
INNER JOIN
sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE
c.name LIKE 'DeflectionId' -- write the column you search here
ORDER BY
schema_name, table_name;
Searched inside all of the stored procedure texts to see if a table name has been used inside them:
SELECT DISTINCT
o.name AS Object_Name,
o.type_desc
FROM
sys.sql_modules m
INNER JOIN
sys.objects o ON m.object_id = o.object_id
WHERE
m.definition LIKE '%\[Test_Results_LU\]%' ESCAPE '\';
or
SELECT name
FROM sys.procedures
WHERE Object_definition(object_id) LIKE '%Test_Results_LU%'
(from this link: Search text in stored procedure in SQL Server )
Used Object Explorer view to see if a table with the similar/same name and size exists in the database.
Do you think there are other ways that I can use to investigate it better?
Are these steps efficient at all? How would you do it?
Those are all reasonable things to check. One more thing to do would be to turn on profiling or auditing, depending on your SQL server version, and actually monitor for the tables being used for a reasonable time period. You may not be able to do that with a production system, and it's still not 100% guaranteed - what if there's an important table that's only queried once a year?
https://dba.stackexchange.com/questions/40960/logging-queries-and-other-t-sql
https://learn.microsoft.com/en-us/sql/relational-databases/security/auditing/view-a-sql-server-audit-log?view=sql-server-2017
One other suggestion before dropping the tables is to explicitly remove access to them (either with DENY/REVOKE or rename them to table-name_purge) for a week or two and see if anyone complains. If they don't, then it's probably safe to make a backup and then drop them.
A couple of other places to check. Both of these rely on data that is
cached automatically by the system
not persisted between restarts
can be dropped at any time.
so absence from these results does not prove that the table is not used but you may find evidence that a table definitely is in use.
SELECT [Schema] = OBJECT_SCHEMA_NAME(object_id),
[ObjectName] = OBJECT_NAME(object_id),
*
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID()
And in the plan cache
USE YourDB
DROP TABLE IF EXISTS #cached_plans, #plans, #results
DECLARE #dbname nvarchar(300) = QUOTENAME(DB_NAME());
SELECT dm_exec_query_stats.creation_time,
dm_exec_query_stats.last_execution_time,
dm_exec_query_stats.execution_count,
dm_exec_query_stats.sql_handle,
dm_exec_query_stats.plan_handle
INTO #cached_plans
FROM sys.dm_exec_query_stats;
WITH distinctph
AS (SELECT DISTINCT plan_handle
FROM #cached_plans)
SELECT query_plan,
plan_handle
INTO #plans
FROM distinctph
CROSS APPLY sys.dm_exec_query_plan(plan_handle);
WITH XMLNAMESPACES (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
SELECT cp.*,
st.text,
[Database] = n.value('#Database', 'nvarchar(300)'),
[Schema] = n.value('#Schema', 'nvarchar(300)'),
[Table] = n.value('#Table', 'nvarchar(300)')
INTO #results
FROM #cached_plans cp
JOIN #plans p
ON cp.plan_handle = p.plan_handle
CROSS APPLY sys.dm_exec_sql_text(sql_handle) st
CROSS APPLY query_plan.nodes('//Object[#Database = sql:variable("#dbname") and #Schema != "[sys]"]') qn(n);
SELECT *
FROM #results

I want to find column name in my database - is it possible?

My database name is CARE_DynamicsAX and I want to find a column name workerStatus
select * from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME = 'workerStatus'
If I'm not wrong, you are trying to find the Table where you have a column name as workerStatus. If that is the case, you might run this query to find the same.
This works for the column names from TABLES for SQL Server.
This query would run under the assumption that you know that the column name that you are searching starts with workerStat
SELECT c.name AS ColName, t.name AS TableName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE 'workerStat%'

SQL Query to search schema of all tables

I am working on a SQL Server 2008 Db that has many tables in it (around 200). Many of these tables contain a field by the name "CreatedDate". I am trying to identify all the table schema with this particular field.
Is there a SQL query to do this?
I would query the information_schema - this has views that are much more readable than the underlying tables.
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%create%'
You can also try doing this using one of many third party tools that are available for this.
Queries are great for simple searches but if you need to do more manipulation with data, search for references and such this is where you can do a much better job with these.
Also, these come in very handy when some objects are encrypted and you need to search for
I’m using ApexSQL Search which is free but there are also many more (also free) on the market such as Red Gate or SSMS Tool Pack.
select object_name(c.object_id) as table_name
, schema_name(t.schema_id) as schema_name
from sys.columns c
join sys.tables t on c.object_id = t.object_id
where c.name=N'CreatedDate';
It gets a little more complicated if you want alsoother table properties, but you'll refer to the object catalog views like sys.tables, sys.columns etc.
My favorite...
SELECT objParent.name AS parent, obj.name, col.*
FROM sysobjects obj
LEFT JOIN syscolumns col
ON obj.id = col.id
LEFT JOIN sysobjects objParent
ON objParent.id = obj.parent_obj
WHERE col.name LIKE '%Comment%'
OR obj.name LIKE '%Comment%'
Above I'm searching for "Comment".
Drop the percent signs if you want a direct match.
This searches tables, fields and things like primary key names, constraints, views, etc.
And when you want to search in StoredProcs after monkeying with the tables (and need to make the procs match), use the following...
SELECT name
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%Comment%'
Hope that helps, I find these two queries to be extremely useful.
For me I only have read access to run querys so I need to use this function often here is what I use:
SELECT *
FROM INFORMATION_SCHEMA.TABLES
where TABLES.TABLE_NAME like '%your table name here%'
You can replace .TABLES with .COLUMNS then it would look like this:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE columns.COLUMN_NAME like '%your column name here%'
Use this query :
SELECT
t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name , *
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
Where
( c.name LIKE '%' + '<ColumnName>' + '%' )
AND
( t.type = 'U' ) -- Use This To Prevent Selecting System Tables
Same thing but in ANSI way
SELECT
*
FROM
INFORMATION_SCHEMA.TABLES
WHERE
TABLE_NAME IN (
SELECT
TABLE_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLUMN_NAME = 'CreateDate'
)
You do not need to type SQL Query for this in SQL Server 2008.
In SSMS Object Explorer choose Databases or Tables of the required database (if you need to search in one database), open menu View--> Object Explorer Details (alternatively press F7), type %CreatedDate% in Search textbox, ENTER, enjoy

Resources