Properly retrieve table ID in SQL Server - sql-server

The answer here says that the info is retrieved from sys.objects view. However this view has only table name field for the schema it has schema_id.
Does it use a self relation for that object_id() function or it queries some other system table/view
to get the schema name?
I can't use object_id() directly, since my code of:
std::string query = "SELECT object_id(?)";
fails with the error because binding parameter is prohibited inside the SELECT clause of the query.
So I need to write the actual query to retrieve it.
Could someone please help?
Basically I'm looking for something like:
SELECT object_id from sys.objects WHERE name = <table_name> AND schema = <schema_name>.
However, I don't see where can I get the schema field...
EDIT:
It looks like the correct query will be
SELECT object_id FROM sys.objects o, sys.schemas s WHERE s.schema_id = o.schema_id AND o.name = <table_name> AND s.name = <schema_name>
but trying to run it Management Studio I don't get any rows.

So, the last query I posted is correct.
The problem was I needed to issue:
USE db_name;
because apparently even though my ODBC string contains DB nameI had to explicitly issue "USE" command.

Related

Where does Visual Studio 2013 sql schema compare tool get its view definition from

So I was trying to compare the view definition I got from this location...
Select smv.definition as VIEW_DEFINITION, v.name AS TABLE_NAME,
iv.IS_UPDATABLE FROM sys.all_views AS v JOIN sys.sql_modules AS smv ON
smv.object_id = v.object_id Join INFORMATION_SCHEMA.Views as iv
On iv.TABLE_NAME = v.name where v.name = #name
Also compared against the value at this location
SELECT * FROM INFORMATION_SCHEMA.Views where TABLE_NAME = #name
Now just for clarity I used to grab from the second location but it turns out it truncates the definition at 4000 characters while the first query does not truncate the definition..
But here is the things both of those definitions (assuming the are short enough to not truncate) match. But when I go into the sql schema compare tool the view definition that shows in that tool does NOT match the view definition stored in either of those locations.
Give an example.
Lets say the view is simple dbo.view_test
CREATE VIEW dbo.view_test
AS
SELECT db.dbo.tbl_view_test.col1, db.dbo.tbl_view_test.col1
FROM dbo.tbl_view_test
GO
So lets say THAT'S whats showing up in the sql comparison output from visual studio 2013 all seems normal...but when I go and pull the definition from either of the above queries it looks like this.
CREATE VIEW dbo.vw_test
AS
SELECT db.dbo.tbl_view_test.col1, db.dbo.tbl_view_test.col1
FROM dbo.tbl_view_test
GO
So somewhere along the way the view definition got out of whack with the view...its not supposed to be vw_test its supposed to be view_test.
SO I guess what I'm wondering is where does the schema compare tool pull its view definition from that is different than what I am returning...and why/how could the get out of sync for the view. Because they aren't the same.. the view in the database is named view_test so how did its definition get modified to something else (vw_test) and the two queries above show that difference but where ever the sql compare tool in visual studio looks it grabs the correct definition.
As you can see in the attached image. running the two queries above both pointed at the view in question from the same database shows that the name of the view is not the same as the name for the view in its view definition.
But when I use VS2013 schema compare pointed at teh same database the view definition is correct anf the Create View is
So what I find myself wondering..is where is VS pulling that view definition from that it differs from the one I return when I query sql myself..
Update:: have now tried all of the following sql scripts all pulled from stack overflow answers as to where to pull the view definition
SELECT * FROM INFORMATION_SCHEMA.Views where TABLE_NAME =
'view_disc_join_cc_info_component'
Go
Select smv.definition as VIEW_DEFINITION, v.name AS TABLE_NAME,
iv.IS_UPDATABLE FROM sys.all_views AS v JOIN sys.sql_modules
AS smv ON smv.object_id = v.object_id Join INFORMATION_SCHEMA.Views
as iv On iv.TABLE_NAME = v.name where v.name =
'view_disc_join_cc_info_component'
GO
SELECT definition, uses_ansi_nulls, uses_quoted_identifier, is_schema_bound
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('dbo.view_disc_join_cc_info_component');
GO
select name, OBJECT_DEFINITION(object_id) from sys.objects where type = 'V'
and name = 'view_disc_join_cc_info_component'
GO
SELECT OBJECT_DEFINITION (OBJECT_ID('dbo.view_disc_join_cc_info_component'))
AS ObjectDefinition;
GO
select c.text from sysobjects o join syscomments c on c.id = o.id where
o.name = 'view_disc_join_cc_info_component' and o.type = 'V'
Go
None of the above scripts show the view defintion Create Claus as matching the view name as it should....I only see that in the Microsoft compare tool.
It's the result of an sp_rename that someone ran on your server. In the example below, after the call to sp_rename, the name of the object will be changed to vw_1 in sys.objects and object explorer, but the definition from syscomments and sys.sql_modules will still show View_1. Now if you right click on the object in object explorer and script a modify, management studio will do a find/replace and fix the problem in the generated alter script, which is what it sounds like the schema compare is doing for you.
CREATE VIEW [dbo].[View_1]
AS
SELECT dbo.Table_1.*
FROM dbo.Table_1;
select *
from
sys.objects
where
name like 'V%'
select *
from
syscomments where text like '%View%';
select *
from
sys.sql_modules
where
[definition] like '%View%';
sp_rename 'View_1', 'vw_1';

Where are views stored in SQL Server

I'm a SQL Server newbie. I've tried foraging around on the web for a while but could not get my question answered. Can anyone please tell me where exactly is a view stored in SQL server 2008 database?
The pedantic answer to your question is... only Microsoft knows exactly where view metadata is physically stored. In the move from SQL 2000 to SQL 2005 (on which 2008 is based) MS got rid of direct access to system tables where views used to be literally stored (dbo.sysviews and dbo.syscomments) and added a layer of abstraction (via the hidden resources database) which means you can only access meta data about views via catalog views. INFORMATION_SCHEMA is an ANSI compliant set of catalog views. While marginally useful for their relative portability between versions, often more information is available from the sql 2008 catalog views - in this case sys.views and sys.sql_modules
Be aware that views can be created with the ENCRYPTION option set which encrypts the sys.comments record(s) that contain the SQL definition of the view. But if not encrypted, then sp_helptext [MyView] will give you a quick look at the definition.
edited as per 1st comment below, to replace "sys.comments" with "sys.sql_modules"
Note: Based on this post
http://improve.dk/archive/2012/08/27/where-does-sql-server-store-the-source-for-stored-procedures.aspx, is very likely that the definition of views are stored (also) in sys.sysobjvalues system table.
The list of all user T-SQL modules (within SQL Server 2008) can be queried using sys.sql_modules system view (link). Here, you can find the definitions of user views (column definition):
SELECT QUOTENAME(s.name)+'.'+QUOTENAME(o.name) AS full_object_name,
m.*
FROM sys.sql_modules m
JOIN sys.objects o ON m.object_id=o.object_id
JOIN sys.schemas s ON o.schema_id=s.schema_id
WHERE o.type='V' -- only view objects
ORDER BY full_object_name
If you run EXEC sp_helptext 'sys.sql_modules' you will get the source code of this system view:
CREATE VIEW sys.sql_modules AS
SELECT object_id = o.id,
definition = object_definition(o.id),
uses_ansi_nulls = sysconv(bit, o.status & 0x40000), -- OBJMOD_ANSINULLS
uses_quoted_identifier = sysconv(bit, o.status & 0x80000), -- OBJMOD_QUOTEDIDENT
is_schema_bound = sysconv(bit, o.status & 0x20000), -- OBJMOD_SCHEMABOUND
uses_database_collation = sysconv(bit, o.status & 0x100000), -- OBJMOD_USESDBCOLL
is_recompiled = sysconv(bit, o.status & 0x400000), -- OBJMOD_NOCACHE
null_on_null_input = sysconv(bit, o.status & 0x200000), -- OBJMOD_NULLONNULL
execute_as_principal_id = x.indepid
FROM sys.sysschobjs o
LEFT JOIN sys.syssingleobjrefs x ON x.depid = o.id AND x.class = 22 AND x.depsubid = 0 -- SRC_OBJEXECASOWNER
WHERE o.pclass <> 100
AND ((o.type = 'TR' AND has_access('TR', o.id, o.pid, o.nsclass) = 1)
OR (type IN ('P','V','FN','IF','TF','RF','IS') AND has_access('CO', o.id) = 1)
OR (type IN ('R','D') AND o.pid = 0))
You can see that this view queries another system object sys.sysschobjs that, I think, is the system table used to store definition of views.
Note 1: Using INFORMATION_SCHEMA.VIEWS to find definition of a view is not a reliable method because INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION column definition is convert(nvarchar(4000), object_definition(object_id)) (max. 4000 chars).
Note 2: Instead, you should use sys.sql_modules.definition column: definition = object_definition(o.id). If you look at object_definition function (link) you will see that return type is nvarchar(max).
If you mean the tables the view produces then the answer is that they aren't stored at all. A view is just a query, and that is all it stores. When you query a view the db engine just fetches your view query's results and then queries those.
DB engines can store 'materialized' views, but that's a different topic.
In a system table.
The following query will retrieve them...
SELECT TABLE_NAME as ViewName,
VIEW_DEFINITION as ViewDefinition
FROM INFORMATION_SCHEMA.Views
To view edit them normally you would look in the view folder under tables in studio manager.
You can create/edit them from this folder using the designer or write scripts.
View is a simple SQL statement that is stored in database schema (INFORMATION_SCHEMA.Views). So when ever we call the view the SQL statement gets executed and return the rows from main physical table.
You can also tell the view as a Logical table that store the defination (the sql statement) but not the result.
You can see the defination using below statement, as said by Dan above, Only if the view defination is Not encrypted:
SELECT TABLE_NAME as ViewName, VIEW_DEFINITION as ViewDefinition FROM INFORMATION_SCHEMA.Views
More details on View # MSDN.

Is there a way to retrieve the view definition from a SQL Server using plain ADO?

I'm successfully extracting column definitions from databases hosted on a SQL server using the ADO Connection OpenSchema() call in its various incarnations so I can programmatically recreate those tables in another SQL database. So far, so good.
The main interaction with the above tables happens using multiple views; while OpenSchema() is able to return the column definitions for the view in the same way that it returns column definitions for a table, a crucial bit of information is missing - which table and column in the underlying tables the column in the view maps to.
I tried to access the SQL command used to create the view using ADOX Catalog Views, but it appears that the OLEDB driver for SQL Server that we're using doesn't support this functionality.
Is there any way to get at this information for the view configuration via ADO, either in a way that states "ColumnX maps to ColumnY in table Z" or in the form of the actual SQL command used to create the view?
Which version of SQL Server?
For SQL Server 2005 and later, you can obtain the SQL script used to create the view like this:
select definition
from sys.objects o
join sys.sql_modules m on m.object_id = o.object_id
where o.object_id = object_id( 'dbo.MyView')
and o.type = 'V'
This returns a single row containing the script used to create/alter the view.
Other columns in the table tell about about options in place at the time the view was compiled.
Caveats
If the view was last modified with ALTER VIEW, then the script will be an ALTER VIEW statement rather than a CREATE VIEW statement.
The script reflects the name as it was created. The only time it gets updated is if you execute ALTER VIEW, or drop and recreate the view with CREATE VIEW. If the view has been renamed (e.g., via sp_rename) or ownership has been transferred to a different schema, the script you get back will reflect the original CREATE/ALTER VIEW statement: it will not reflect the objects current name.
Some tools truncate the output. For example, the MS-SQL command line tool sqlcmd.exe truncates the data at 255 chars. You can pass the parameter -y N to get the result with N chars.
Microsoft listed the following methods for getting the a View definition: http://technet.microsoft.com/en-us/library/ms175067.aspx
USE AdventureWorks2012;
GO
SELECT definition, uses_ansi_nulls, uses_quoted_identifier, is_schema_bound
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('HumanResources.vEmployee');
GO
USE AdventureWorks2012;
GO
SELECT OBJECT_DEFINITION (OBJECT_ID('HumanResources.vEmployee'))
AS ObjectDefinition;
GO
EXEC sp_helptext 'HumanResources.vEmployee';
For users of SQL 2000, the actual command that will provide this information is:
select c.text
from sysobjects o
join syscomments c on c.id = o.id
where o.name = '<view_name_here>'
and o.type = 'V'
SELECT object_definition (OBJECT_ID(N'dbo.vEmployee'))
You can get table/view details through below query.
For table :sp_help table_name
For View :sp_help view_name
SELECT definition, uses_ansi_nulls, uses_quoted_identifier, is_schema_bound
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('your View Name');
This example:Views Collection, CommandText Property Example (VB)
Shows how to use ADOX to maintain VIEWS by changing COMMAND related to VIEW.
But instead using it like this:
Set cmd = cat.Views("AllCustomers").Command
' Update the CommandText of the command.
cmd.CommandText = _
"Select CustomerId, CompanyName, ContactName From Customers"
just try to use this way:
Set CommandText = cat.Views("AllCustomers").Command.CommandText

How to stop stored procs from whining about a missing column that I am about to delete in SQL Server 2008?

I am deleting a column from one of the frequently used tables in my database.
Last time I did this errors started to crawl up from all sorts of stored procs that I had long forgotten existed; complaining about the missing column. (only when that stored proc was called)
so, I dont want to get winded up with these things again, I want to make sure all stored procs are free of that column before I actually delete it.
What is the best way to search through all stored procs (and I have quite a lot of them) and remove the reference to that column?
I tried to find an option in the menu to do this but I did not find anything very obvious to do this.
any help, (other than telling me to go through them all one by one) is appreciated.
ps: of course, doesnt mean that I will depreciate your comment if you do tell me. I will only downvote :P
(nah, just kidding!)
To add to the various TSQL solutions, there is a free tool from Red Gate that integrates into SSMS: SQL Search
Use this script. It will also return triggers. If many tables has column with the same name you can add tale name to the where too. This script works on MSSQL 2000, 2005. I haven't tested it on 2008, but it should work fine too.
SELECT o.name
FROM sysobjects o
INNER JOIN syscomments c ON o.id = c.id
WHERE c.text like '%column_name%'
Edit: If you want to filter it only to store procedures add AND type ='P' to the where clause
Red Gate Software's SQL Prompt 5 has a couple of new features that might be useful in this situation:
Column Dependencies: hover over a column name in a script and up pops a window containing a list of all the objects that use that column
Find Invalid Objects: show objects across the database that can't be used, often because they use columns that have been deleted
You can download a 14-day free trial to see if the tool would be useful for you.
Paul Stephenson
SQL Prompt Project Manager
Red Gate Software
You can use Dependence option for that table to find the Dependent object or list of Procedure or function which are depend on this table.
Use below script
sp_depends 'TableName'
another option is create script for that column containing but that will filter all the text in the procedure or function.
EDIT: sorry, my bad. here's the code for searching within the stored procedure's code
The following stored procedure should be able to list all the stored procedures whose text contain the desired string (so, place your column name in it and fire away):
CREATE PROCEDURE Find_Text_In_SP
#StringToSearch varchar(100)
AS
SET #StringToSearch = '%' +#StringToSearch + '%'
SELECT Distinct SO.Name
FROM sysobjects SO (NOLOCK)
INNER JOIN syscomments SC (NOLOCK) on SO.Id = SC.ID
AND SO.Type = 'P'
AND SC.Text LIKE #stringtosearch
ORDER BY SO.Name
GO
Usage:
exec Find_Text_In_SP 'desired_column_name'
Source here
If you use MS SQL later than version 2000, it's better to search sys.sql_modules rather than sys.syscomments, since syscomments only hold records of nvarchar(4000), and the text you are looking for may be split into two records.
So while you can use a query like this from MSDN
SELECT sm.object_id, OBJECT_NAME(sm.object_id) AS object_name, o.type, o.type_desc, sm.definition
FROM sys.sql_modules AS sm
JOIN sys.objects AS o ON sm.object_id = o.object_id
WHERE sm.definition like '%' + #ColumnName + '%'
ORDER BY o.type;
you should be aware that this search finds any procedure containing that text, regardless of whether it is an actual column name and which table the column belongs to.

How can I get the definition (body) of a trigger in SQL Server?

Unable to find a SQL diff tool that meets my needs, I am writing my own. Between the INFORMATION_SCHEMA and sys tables, I have a mostly-complete working version. But one thing I can't find in the metadata is the definition of a trigger, you know, the actual SQL code. Am I overlooking something?
Thanks.
Thanks, Pete, I didn't know about that!
Scott, I'm working with very basic hosting packages that don't allow remote connections to the DB. I don't know from the specs on RedGate (which I can't afford anyway) whether they provide a workaround for that, and although there are also API's out there (such as the one from Apex), I didn't see the point in investing in a solution that was still going to require more programming on my part. :)
My solution is to drop an ASPX page on the site that acts as a kind of "schema service", returning the collected metadata as XML. I set up a little AJAX app that compares any number of catalog instances to a master and shows the diffs. It's not perfect, but a major step forward for me.
Thanks again!
sp_helptext works to get the sql that makes up a trigger.
The text column in the syscomments view also contains the sql used for object creation.
SELECT
DB_NAME() AS DataBaseName,
dbo.SysObjects.Name AS TriggerName,
dbo.sysComments.Text AS SqlContent
FROM
dbo.SysObjects INNER JOIN
dbo.sysComments ON
dbo.SysObjects.ID = dbo.sysComments.ID
WHERE
(dbo.SysObjects.xType = 'TR')
AND
dbo.SysObjects.Name = '<YourTriggerName>'
For 2005 and 2008 you can use the OBJECT_DEFINITION() function
To expand on SQLMenace's answer, here's a simple query to return all triggers and their definitions from a database:
SELECT
sysobjects.name AS trigger_name,
OBJECT_NAME(parent_obj) AS table_name,
OBJECT_DEFINITION(id) AS trigger_definition
FROM sysobjects
WHERE sysobjects.type = 'TR'
you have various ways to view SQL Server trigger definition.
querying from a system view:
SELECT definition
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('trigger_name');
Or
SELECT OBJECT_NAME(parent_obj) [table name],
NAME [triger name],
OBJECT_DEFINITION(id) body
FROM sysobjects
WHERE xtype = 'TR'
AND name = 'trigger_name';
definition using OBJECT_DEFINITION function:
SELECT OBJECT_DEFINITION(OBJECT_ID('trigger_name')) AS trigger_definition;
definition using sp_helptext stored procedure:
EXEC sp_helptext
'trigger_name';
this query return trigger with its name and body.
Select
[tgr].[name] as [trigger name],
[tbl].[name] as [table name] ,
OBJECT_DEFINITION(tgr.id) body
from sysobjects tgr
join sysobjects tbl
on tgr.parent_obj = tbl.id
WHERE tgr.xtype = 'TR'

Resources