Where are views stored in SQL Server - 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.

Related

how to automate creation of view or synonyms to another database and which to use

I have a database maintained by a program. During updates all stored procedures are wiped out. I create reports using stored procedures so all of my custom stored procedures have to be scripted then reloaded when upgrades are done. Also, during the process of using tools within the software views will be created that link two tables. one being an original table and the other typically being a custom fields table.
I have a new database where I want to create the stored procedures that would remain unchanged during upgrades. That being said I have the following questions. What is the best way to do this.
View to the tables which are in one schema and views to the view which are in another but create it in a way that all the views I create are in one schema giving precedent to the views rather than tables. Create synonyms to the tables and views.
The next question would be how to script this to create the object because there are hundreds of tables and view.
Script 1 would create the synonym or view and script 2 can find all the tables or views. how would I be able to run them together or would I just have to use script 2 to create scripts to run in the second database.
Any suggestions would be great and any help understanding which would be best views or synonyms would be great. I want to learn not just be given the answer and if there is any other ideas to accomplish my goal of separating the stored procedures from the main db would be great.
***Script 1***
create synonym table1 for db1.dbo.table1
***Script 2***
select a.name from sys.tables a
inner join sys.schemas b
on a.schema_id = b.schema_id
where a.type = 'U'
You could generate script:
select
FORMATMESSAGE('CREATE SYNONYM %s FOR db1.%s.%s;', -- here goes template
QUOTENAME(a.name),
QUOTENAME(SCHEMA_NAME(b.[schema_id])),
QUOTENAME(a.name)
) AS query_to_run
from sys.tables a
inner join sys.schemas b
on a.schema_id = b.schema_id
where a.type = 'U';
db<>fiddle demo
Using metadata you could build any kind of script, then copy the result from SSMS grid to query pane and execute it.

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';

SQL Server - Querying sysobjects

I notice that when I query dbo.sysobjects, to determine all the objects in my database, it also picks up all system views whose name starts with 'syncobj_'. These have an xtype of 'V' and there doesn't appear to be any way I can know these are system views, and not my own, except by examining the name of the view. Is there some other way? I would like to exclude these from a query I'm in the process of creating.
See OBJECTPROPERTY:
IsMSShipped
Any schema-scoped object
Object created during installation of SQL Server. 1 = True 0 = False
Use it something like:
SELECT * from sysobjects where OBJECTPROPERTY(ID,N'IsMSShipped') = 0
It's documentation is a bit off though - it also assists you with excluding other objects added "by" SQL Server at a later date also - e.g. any replication related objects are also considered to be IsMSShipped.
Try something like:
select *
from sysobjects
where name NOT IN (
select name from sys.system_views
)
Since you are using SQL Server 2008, there is very little reason to continue using the outdated compatibility view sysobjects. You should instead use the catalog view sys.objects, introduced in SQL Server 2005. As an added bonus, you don't need to call an external OBJECTPROPERTY() function for every single row, since it contains a column called is_ms_shipped that reveals the same information.
SELECT OBJECT_SCHEMA_NAME([object_id]), name, type
FROM sys.objects
WHERE is_ms_shipped = 0;

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

Stored procedures reverse engineering

We're having problem with a huge number of legacy stored procedures at work. Do you guys recommend any tool the can help better understand those procedures? Some kind of reverse engineering that indentifies inter-procedure dependencies and/or procedure vs. tables dependencies. Can be a free or commercial tool.
Thanks!
The cheaper solution than 'dependency tracker' is the data dictionary table sys.sql_dependencies which from which this data can be queried from the data dictionary. Oracle has a data dictionary view with similar functionality called DBA_DEPENDENCIES (plus equivalent USER_ and ALL_ views) . Using the other data dictionary tables (sys.tables/DBA_TABLES) etc. you can generate object dependency reports.
If you're feeling particularly keen you can use a recursive query (Oracle CONNECT BY or SQL Server Common Table Expressions) to build a complete object dependency graph.
Here's an example of a recursive CTE on sys.sql_dependencies. It will return an entry for every dependency with its depth. Items can occur more than once, possibly at different depths, for every dependency relationship. I don't have a working Oracle instance to hand to build a CONNECT BY query on DBA_DEPENDENCIES so anyone with edit privileges and the time and expertise is welcome to annotate or edit this answer.
Note also with sys.sql_dependencies that you can get column references from referenced_minor_id. This could be used (for example) to determine which columns were actually used in the ETL sprocs from a staging area with copies of the DB tables from the source with more columns than are actually used.
with dep_cte as (
select o2.object_id as parent_id
,o2.name as parent_name
,o1.object_id as child_id
,o1.name as child_name
,d.referenced_minor_id
,1 as hierarchy_level
from sys.sql_dependencies d
join sys.objects o1
on o1.object_id = d.referenced_major_id
join sys.objects o2
on o2.object_id = d.object_id
where d.referenced_minor_id in (0,1)
and not exists
(select 1
from sys.sql_dependencies d2
where d2.referenced_major_id = d.object_id)
union all
select o2.object_id as parent_id
,o2.name as parent_name
,o1.object_id as child_id
,o1.name as child_name
,d.referenced_minor_id
,d2.hierarchy_level + 1 as hierarchy_level
from sys.sql_dependencies d
join sys.objects o1
on o1.object_id = d.referenced_major_id
join sys.objects o2
on o2.object_id = d.object_id
join dep_cte d2
on d.object_id = d2.child_id
where d.referenced_minor_id in (0,1)
)
select *
from dep_cte
order by hierarchy_level
I've got this to open-up to the community now. Could someone with convenient access to a running Oracle instance post a CONNECT BY recursive query here? Note that this is SQL-server specific and the question owner has since made it clear that he's using Oracle. I don't have a running Oracle instance to hand to develop and test anything.
Redgate has a rather expensive product called SQL Dependency Tracker that seems to fulfill the requirements.
I think the Red Gate Dependency Tracker mentioned by rpetrich is a decent solution, it works well and Red Gate has 30 day trial (ideally long enough for you do do your forensics).
I would also consider isolating the system and running the SQL Profiler which will show you all the SQL action on the tables. This is often a good starting point for building a sequence diagram or however you choose to document these codes. Good luck!
Redgate SQL Doc. the generated documentation included cross-referenced dependency information. For example, for each table, it lists views, stored procedures, triggers etc that reference that table.
What database are the stored procedures in? Oracle, SQL Server, something else?
Edit based on comment: Given you're using Oracle then, have a look at TOAD. I use a feature in it called the Code Roadmap, which allows you to graphically display PL/SQL interdependancies within the database. It can run in Code Only mode, showing runtime call stack dependancies, or Code Plus Data mode, where it also shows you database objects (tables, views, triggers) that are touched by your code.
(Note - I am a TOAD user, and gain no benefit from referring it)
This isn't real deep or thorough, but I think that if you're using MS SQL Server or Oracle (Perhaps Nigel can help with a PL-SQL sample)...Nigel is on to something . This only goes 3 dependencies deep, but could be modified to go however deep you need. It's not the prettiest thing...but it's functional...
select
so.name + case when so.xtype='P' then ' (Stored Proc)' when so.xtype='U' then ' (Table)' when so.xtype='V' then ' (View)' else ' (Unknown)' end as EntityName,
so2.name + case when so2.xtype='P' then ' (Stored Proc)' when so2.xtype='U' then ' (Table)' when so2.xtype='V' then ' (View)' else ' (Unknown)' end as FirstDependancy,
so3.name + case when so3.xtype='P' then ' (Stored Proc)' when so3.xtype='U' then ' (Table)' when so3.xtype='V' then ' (View)' else ' (Unknown)' end as SecondDependancy,
so4.name + case when so4.xtype='P' then ' (Stored Proc)' when so4.xtype='U' then ' (Table)' when so4.xtype='V' then ' (View)' else ' (Unknown)' end as ThirdDependancy
from
sysdepends sd
inner join sysobjects as so on sd.id=so.id
left join sysobjects as so2 on sd.depid=so2.id
left join sysdepends as sd2 on so2.id=sd2.id and so2.xtype not in ('S','PK','D')
left join sysobjects as so3 on sd2.depid=so3.id and so3.xtype not in ('S','PK','D')
left join sysdepends as sd3 on so3.id=sd3.id and so3.xtype not in ('S','PK','D')
left join sysobjects as so4 on sd3.depid=so4.id and so4.xtype not in ('S','PK','D')
where so.xtype = 'P' and left(so.name,2)<>'dt'
group by so.name, so2.name, so3.name, so4.name, so.xtype, so2.xtype, so3.xtype, so4.xtype
How to find the dependency chain of a database object (MS SQL Server 2000(?)+)
by Jacob Sebastian
Every time he needs to deploy a new report or modify an existing
report, he needs to know what are the database objects that depend on
the given report stored procedure. Some times the reports are very
complex and each stored procedure might have dozens of dependent
objects and each dependent object may be depending on other dozens of
objects.
He needed a way to recursively find all the depending objects of a
given stored procedure. I wrote a recursive query using CTE to achieve
this.
The single best tool for reverse engineering is by APEX. Its amazing. It can even trace into .NET assemblies and tell you where the procs are used. Its by far the deepest product of its kind. RedGate has great other tools but not in this case.

Resources