sp_help - table is referenced by an 'empty string' schema bound view - sql-server

I'm trying to systematically determine the differences in schema between a local database and a remote database administered by someone else. I've had the remote administrator run a script that executed sp_help and sp_helptext on a variety of objects.
There is one difference I don't know how to account for. On my local system sp_help on one table produces a line of message output No views with schema binding reference table 'dbo.tbl'.
On the remote system, the output was 'Table is referenced by views' followed by a blank line. The query was run with output as text so this indicates on the remote machine a one row result set was produced with an empty string (or NULL?) value.
How can that happen? If I create a schema bound view locally I get the 'Table is referenced by views' output followed by the name of the view plainly displayed. What scenario on the remote machine could be producing this result set without any view name recorded?

To answer your question requires knowledge of the internal workings of sp_help. You are welcome to descend into the depths of procedures that are called by sp_help. If you do, you will see that this procedure uses sysdepends - which is both not "dependable" and obsolete. Ref: https://learn.microsoft.com/en-us/sql/relational-databases/system-compatibility-views/sys-sysdepends-transact-sql . The short answer is that something has been altered/renamed in a way that is not captured in sysdepends.

Related

Unable to get definition for Sales.vw_CustomerOrders view in AdventureWorks2017 sample database

Looking at the AdventureWorks2017 database I ran across a view called Sales.vw_CustomerOrders. Wondering where it was getting its data I tried to query the object definition and the results came back NULL
SELECT definition
FROM sys.sql_modules
WHERE object_id = Object_id('Sales.vw_CustomerOrders')
I noticed the icon is slightly different from the other views and SSMS won't allow you to generate a create statement either (only a drop). What is this particular view? Why can't you generate a create statement for it? How can I find out how it gets its data?
TIA
As #MeyssamToluie mentioned in comments, view Sales.vw_CustomerOrders is not part of the out-of-box AdventureWorks database.
The different SSMS icon indicates the object is encrypted. When a view is created using WITH ENCRYPION option, the definition is obfuscated, not visible in the sys.sql_modules system view, and the CREATE cannot be scripted via normal methods. You'll find undocumented/unsupported ways to get the clear text definition of obfuscated objects with an internet search.
Use OBJECTPROPERTY to identify the encryption status of the view:
SELECT OBJECTPROPERTY(object_id, 'IsEncrypted') AS IsEncrypted, *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'Sales.vw_CustomerOrders');

Why script generated by SSMS shown in red is different from script stored in system tables

Why script generated by SSMS shown in red is different from script stored in system tables. Please notice stored procedure names in query, query result and Object explorer.
i.e.
All these methods are giving me same script
sql_module
object_definition
sp_helptext
However when generated from SSMS, right click -> script as Create or Modify is giving a different script.
How is it possible and generating different scripts.
The answer can be confusing.
The Stored procedure getBudgets4programManager2 was renamed (very likely using sp_rename https://msdn.microsoft.com/en-us/library/ms188351.aspx), so the original definition does not match the new name. BTW. Notice that the definition stored in metadata will always change the DDL command to CREATE in case of issuing an ALTER PROCEDURE statement.
At the same time, SSMS scripting features will not simply get the definition from metadata as it has an object representation of the stored procedure, it will normalize the schema name & object name, and it may also normalize the DDL command accordingly (CREATE/ALTER). Notice that the schema is showing it is normalized (i.e. [dbo]), and that the current name is also normalized.
As for why the metadata definition is not renamed at the same time you rename the object. The answer is not 100% clear, but such change would affect any features in the SQL Server engine that relies on the definition, including using the WITH ENCRYPTION option on ALTER/CREATE PROCEDURE as well as the verification of digital signatures.
As far as I know, other elements in both versions of the scripts should remain intact (comments, blank spaces, etc.).
I hope this information helps.

How do i get list of Synonyms were used in the stored procedure

I think this is a rather valid question, and I'm not sure why it was marked for closure unless this is also a duplicate.
As Ben Thul points out in his comment:
One of the points of synonyms is to abstract the actual location of an
object so that you can change it in only one place (i.e. the synonym
definition) and anywhere the synonym is used automatically gets the
right location.
This is certainly an excellent reason for synonyms (if not THE reason) but consider a scenario where you have a large SQL codebase that you inherited as the sole manager. You manage the data tables, views and stored procedures and inside this database there are near-thousands of database objects.
One day, (oops!) an update on a data feed breaks an internal process. It is now your task to inspect any broken code and fix the issue. After a bit of searching, you find an INSERT reference in an SP that doesn't seem to point to a data table? Therefore, you assume it is a synonym and you now need to find the underlying table so that you can further inspect what may be broken.
This is a valid case and, in fact, is exactly where I am today. The original poster takes the logical need one step further than just asking for a list of database object synonyms. Instead, he asks if there is a way to list all synonyms used in one stored procedure?
Personally, I'd be fine with a list of all synonyms, however, answering his question does get one step closer to the end-need.
ORIGINAL QUESTION
Can some one please help me out, To get the list of Synonyms were used in the Stored procedure (Example: Procs.myproc)
I believe that you can not do that. The only thing you can do is to find all the name of synonyms and find these strings in stored procedure.
You can get all names of synonyms by following query:
SELECT
s.name,
COALESCE(PARSENAME(s.base_object_name,4),##servername) AS serverName,
COALESCE(PARSENAME(s.base_object_name,3),DB_NAME(DB_ID())) AS dbName,
COALESCE(PARSENAME(s.base_object_name,2),SCHEMA_NAME(SCHEMA_ID())) AS schemaName,
PARSENAME(s.base_object_name,1) AS objectName
FROM sys.synonyms s
ORDER BY 2,3,4,5
then you go 1 by 1 in loop and check the presence "objectName" in the stored procedure

SQL Server Profiler suddenly says Encrypted Text

Recently I noticed that a stored proc we are trying to profile failed to appear in the profiling output.
After adding in SP:StmtStarting and SP:StmtCompleted events, I noticed the TextData reported as
-- Encrypted text
.. but the stored procedure is not encrypted.
This has only recently started happening - we used to profile this SP perfectly fine, and I can't figure what has changed.
Any suggestions would be gratefully received.
UPDATE: The SP is definitely not encrypted. I've created new SP's on the box, and I see SP:BatchStarting event with the new SP's name. With the old SP, I don't see the BatchStarting event, but I do see the statements within the SP executing.
However I need to see the values of the parameters the SP is being called with, as they are table types. Originally I could see the table types being instantiated and populated before the SP is called.
So I figured this out in case anyone finds it useful.
I have table type parameters to this stored procedure. One of the parameters is passed a lot of data (i.e. a C# DataTable with >5000 rows). Without this quantity of data the stored proc profiled fine.
I guess there must be some cut-off at which point Profiler does not show all of the data being passed in.
Someone has altered the stored procedure and added the 'WITH ENCRYPTION' hint, which will cause this behavior. Alter the stored procedure and remove that hint and you'll start seeing the text of the proc again.
Also to note, if you don't have the original code, you will not be able to decrypt the text of the proc to issue the ALTER statement, so hopefully you have that handy.
Here's a decent run down of this option: Options for hiding SQL Server code
Moving the Trace Properties from the default of OnlySP(<your database here>)(user,default) to TSQL or TSQL_Replay unveiled the SQL being used for me, ... Go to File|Properties... and change the [Use the template:] drop-down combobox.

SET QUOTED IDENTIFIER should be ON when inserting a record

I am stuck in a rather strange problem with SQL Server 2005, which throws
"SET QUOTED IDENTIFIER should be on when inserting record"
(using as SP) to the particular table. This worked fine earlier but is throwing this error randomly.
I have verified the SP. We didn't manually specify SET QUOTED IDENTIFIER settings inside, so it must be ON by default.
Can someone clarify what could be the problem?
The table must be created with SET QUOTED IDENTIFIER ON right? I didn't check the table script yet.
I have observed that this problem only occur with the SPs doing insert or update on a date column (modifiedAt)... A sample value is '2009-08-10 06:43:59:447'..
Is there a problem with the values passed?
After a long struggle we were able to fix this problem. I just wanted to share the reason.
Our build team maintains a separate in-house tool to deploy scripts, which internally triggers the SQLCMD (shell) utility to execute T-SQL scripts in a db.
Here is the culprit: by default, QUOTED_IDENTIFIER is OFF when running in SQLCMD mode!
Every script run through this tool is created with QUOTED IDENTIFIER OFF. We are the only module which uses indexed views. All the remaining stories you know well in my previous posts :(
NOTE: I am going to vote everyone's post as useful.
Script the stored proc, ensure/change SET options, run the ALTER PROC to ensure SET QUOTED IDENTIFIER ON is set.
Why?
The setting of "SET QUOTED IDENTIFIER" is defined at creation time for stored procs and is always "ON" for tables. Source, BOL.
When a table is created, the QUOTED
IDENTIFIER option is always stored as
ON in the table's metadata even if the
option is set to OFF when the table is
created.
When a stored procedure is created,
the SET QUOTED_IDENTIFIER and SET
ANSI_NULLS settings are captured and
used for subsequent invocations of
that stored procedure.
The default for connections can be defined at the server level (sp_configure 'user options') or database level (ALTER DATABASE). For SSMS, it's under "Tools..Options.. Query Execution..SQL Server..ANSI". It's also the default for client libraries too (except DB-LIb).
Now, it you open an SSMS Query Window and start typing "CREATE PROC.." then it uses SSMS settings when you run the code.
And SET QUOTED IDENTIFIER can not be set at run time inside the stored proc. Show me the a reference before you disagree... From the MS BOL link above:
When executed inside a stored
procedure, the setting of SET
QUOTED_IDENTIFIER is not changed.
You have to work hard to run any code with this OFF... so the most likely fix is to ALTER or re-create the stored proc.
I was just reading this article by Erland Sommarskog, The Curse and Blessings of Dynamic SQL, and it includes the following paragraph in regards to the SET QUOTED IDENTIFIER setting:
The default for this
setting depends on context, but the
preferred setting is ON, and it must
be ON in order to use XQuery, indexed
views and indexes on computed columns.
Does your stored procedure make use of XQuery, indexed views or indexes on computed columns at all?
In SQL Server 2005, SET QUOTED IDENTIFIER is OFF by default, not ON (unless using an ODBC or OLE connection...see this for more information).
You do not need to create the table with SET QUOTED IDENTIFIER ON to use it.
All you need to do is add SET QUOTED IDENTIFIER ON to the beginning of your SP to enable it for the run of the procedure (and make sure that if you don't wish to leave it on, you have SET QUOTED IDENTIFIER OFF to switch it back).
EDIT
I stand corrected. According to this MSDN Page, SET QUOTED IDENTIFIER is ON by default (unless connection with a DB-Library application.

Resources