SQL Server - Querying sysobjects - sql-server

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;

Related

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.

Orphan constraints in SQL Server database

Running the following query results in all constraints in our client's database. However, several rows in the result set don't seem to have a parent, i.e. parent_object_id = 0 and OBJECT_NAME(parent_object_id) returns NULL.
SELECT name, type_desc, OBJECT_NAME(parent_object_id), parent_object_id
FROM sys.objects
WHERE is_ms_shipped = 0
AND type_desc LIKE '%_CONSTRAINT'
Does this mean there are orphan constraints in the database? If so, how do I remove these?
From their names, I can see they are leftovers from before a large amount changes were made to the structure.
Using sp_helptext I can see they were created using a CREATE DEFAULT statement, e.g.:
CREATE DEFAULT dbo.MyDefault AS 2
This means they are simply unbound defaults, which can be bound using the sp_binddefault according to MSDN, and removed with a simple DROP DEFAULT statement:
DROP DEFAULT dbo.MyDefault
I wasn't aware of this syntax, which apparently will be removed in a future version of SQL Server, according to the aforementioned MSDN article.

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

What is the sql to query SqlServer system databases to find an DB object?

I have a large db with many tables and sprocs, and I want to find and see, for example, if there is a table with a name that has "setting" as part of it. I'm not very familiar with SqlServer's System Databases like master, msdb etc., I know there is a way to query one of those dbs to get what I need back, does someone know how to do it?
Thank you,
Ray.
SQL Server also supports the standard information schema views. Probably better to use them, since this query should also work across different database engines if you ever need to do a migration:
SELECT * FROM INFORMATION_SCHEMA.tables where table_name LIKE '%Settings%'
the table you want is sys.objects
SELECT *
FROM sys.objects
The table with the info you seek is called sysobjects. Here's a query for what you describe:
SELECT * FROM sysobjects WHERE xtype = 'U' AND NAME LIKE '%setting%'
(U is the type for user tables)
For Sql Server 2005
SELECT * FROM sys.objects where type in ('U') and name like '%setting%'

Can DTS Test for Presence of MS-Access Table

I have an Access database in which I drop the table and then create the table afresh. However, I need to be able to test for the table in case the table gets dropped but not created (i.e. when someone stops the DTS package just after it starts -roll-eyes- ). If I were doing this in the SQL database I would just do:
IF (EXISTS (SELECT * FROM sysobjects WHERE name = 'Table-Name-to-look-for'))
BEGIN
drop table 'Table-Name-to-look-for'
END
But how do I do that for an Access database?
Optional answer: is there a way to have the DTS package ignore the error and just go to the next step rather than checking to see if it exists?
SQL Server 2000
I'm not sure whether you can query the system objects table in an Access database from a DTS package.
If that doesn't work, why not just try doing a SELECT * from the Access table in question and then catch the error if it fails?
Try the same T-SQL, but in MS ACCESS the sys objects table is called:
MSysObjects.
Try this:
SELECT * FROM MSysObjects WHERE Name = 'your_table';
and see if it works from there.
You can take a look at these tables if you go to Tools -> Options -> View (a tab) -> and check Hidden Objects, System Objects. So you can see both. If you open the table, you should see your table names, queries, etc. Do not change this manually or the DB could panic :)
Martin.
P.D.: Your If Exists should also check of object type:
IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id(N'[dbo].[Your_Table_Name]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
Microsoft Access has a system table called MSysObjects that contains a list of all database objects, including tables. Table objects have Type 1, 4 and 6.
It is important to reference the type:
... Where Name='TableName' And Type In (1,4,6)
Otherwise, what is returned could be a some object other than a table.

Resources