How to retrieve full definition of external func/proc? - sql-server

I'd like to write a procedure to build the sql code to define all func/procs in given assembly.
It is simple for procedures and scalar functions -
iterating sys.assemblies/modules/objects/parameters I can prepare code for create func/proc.
But I cannot find where the definition of the table returned by the tv function is stored. Scripting of the functions like that is possible, so - the definition of the table have to be written somwhere..
By the way - second question: is there some tool to create sql definition of func/proc basing on C# code ?

Just like Tables, Table-Valued Functions (Inline, SQL MultiStatement, and SQLCLR), and Views are maintained in the sys.columns system catalog view (and sys.all_columns).
SELECT obj.[name], obj.[type_desc], col.[name]
FROM sys.objects obj
INNER JOIN sys.columns col
ON col.[object_id] = obj.[object_id]
ORDER BY obj.[type_desc], obj.[name], col.[name];
You will need to join to sys.types to get the full datatype name.
However, there is very little point to scripting things out as you are doing since:
If the T-SQL wrapper objects (for the SQLCLR methods within the Assembly) were created by a script you wrote, then you already have those CREATE statements, and
If the T-SQL wrapper objects were created by SSDT (with or without Visual Studio), then you already have the "create" script (if you opted to have it get generated upon each build) and the incremental "publish" script.
In either case, those objects were created from a T-SQL script that you should already have. Unless, I suppose, you were handed a Database that had the objects and the deployment scripts aren't available for some reason.
Is there some tool to create T-SQL definition of func/proc based on C# code ?
From the database or the DLL / Assembly? There are some tools that can be used to script any type of object out of the database. You can also use the .NET SMO classes to script out the definitions from the database. If you want to scan the DLL / Assembly, you would need to use the .NET Reflection classes to iterate over each method and look at the SqlFunction, SqlProcedure, SqlFacet attributes / decorators.

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

DB View in DB project in Visual Studio can't see synonym in same project

Our web app uses 4 databases, all on the same server.
The SQL for these databases is stored in 4 projects in our solution.
I have a view in one database that is used in two other databases.
Both of those databases have a synonym to the view, WITH THE SAME NAME. From a database perspective, it makes perfect sense.
[database_1].dbo.Syn_AAAAAA and [database_2].dbo.Syn_AAAAAA both point to [database_3].dbo.vw_AAAAAA.
From a sql server perspective, it makes perfect sense.
Application works fine. Databases are quite happy.
Database1 uses the [synonym ==> view] in stored procedures, and everything is fine. When the code is in the db project, it is fine too.
In database2 PROJECT, I reference the [synonym ==> view] in another view. Of course, works fine in the data base.
BUT in the project, the view that uses the synonym is choking. It's like it is seeing ALL synonyms with that name, even those outside of it's scope, the database it's in.
select y.columnA, y.columnB, y.columnC, _l.columnD_, d3.columnE, d3.columnF
from dbo.TableD d3
inner join (subquery) y
on y.columnA = d3.columnA
left join _dbo.syn_AAAAAA_ l
on _l.columnC_ = d3.columnC
(Underscores denote the error locations from IntelliSense.)
If I can write competent SQL code on the server, why do I have to fight with Visual Studio about storing it in a project?
SQL71501: View: [dbo].[vw_AAAAAA] contains an unresolved reference to an object.
Either the object does not exist or the reference is ambiguous because it could refer to any of the following objects:
[$(ThisDB)].[dbo].[Syn_BBBBBB].[l]::[ColumnName],
[$(ThisDB)].[dbo].[Syn_BBBBBB].[ColumnName] or
[dbo].[Table].[l]::[ColumnName].
SQL71561: View: [dbo].[vw_AAAAAA] has an unresolved reference to object
[$(ThisDB)].[dbo].[Syn_BBBBBB]
Problem lay with the SYNONYM.
CREATE SYNONYM [dbo].[syn_xxxx] FOR [DBName].[dbo].[vw_xxxx]
Had to change it to
CREATE SYNONYM [dbo].[syn_xxxx] FOR [$(DBNameVariable)].[dbo].[vw_xxxx]
Most of the time [DBName] worked, but in this case I had to use the [$(DBNameVariable)].
right click on your db reference, look at the database you're trying to reference, and see if there is a variable for it. (I didn't set this up, so it's a little outside my experience.) My last position, we didn't keep SQL projects in our code solution.

SQL Server extended events: write custom predicates?

We have about 2'000 "old" objects in a sql server database (tables, views etc.) of which we don't really know if they're still in use. I want to create an extended event listener for these objects. I tried to add a giant WHERE clause to the CREATE EVENT SESSION command, consisting of 2'000 [package0].[equal_int64]([object_id], (<objectId>)) statements.
However, the command max length is 3'000 characters, so I cannot do this. And I guess that the performance of this filer wouldn't be too good, anyway...
Now my question is: I can query all possible predicates using select * from sys.dm_xe_objects where object_type= 'pred_compare'. this gives me results such as name=equal_uint64, package_guid=60AA9FBF-673B-4553-B7ED-71DCA7F5E972. the package_guid refers to sys.dm_xe_packages, where several DLLs are referenced which seem to implement a particular predicate.
Would it be possible to define my own "package" and implement a predicate there (which would filter the objectId using a hashtable)? Is it possible somehow to import such a package into SQL server so I could define a custom predicate?
Or does anyone have another idea how to implement such a filter?

Getting the definition of a CLR Stored Procedure

I wrote a CLR stored procedure (to send emails, and not depend from DatabaseMail, as I was told it was more safer).
It works as expected. The thing I want to learn now is how to get the definition from a CLR object (CLR SP, CLR scalar function, etc).
I already tried with:
sys.sql_modules,
sys.system_sql_modules,
OBJECT_DEFINITION()
But it returns a null definition.
Is there any other way to get the definition of a CLR object?
SQLCLR objects have no T-SQL code so there is nothing to store that could be retrieved using the sys.* _sql_modules DMVs or the OBJECT_DEFINITION() built-in function.
If you want the underlying .NET code, that is in the Assembly, which is found in: sys.assembly_files.
SELECT *
FROM sys.assembly_files
WHERE [file_id] = 1;
If you don't have the source code, that can be extracted by disassembling the Assembly.
If you want the CREATE PROCEDURE ... AS EXTERNAL NAME ... ; statement then that would need to be pieced together from several DMVs: sys.assembly_modules, sys.types, sys.parameters, sys.columns. You would also need to use OBJECT_NAME and OBJECT_SCHEMA_NAME built-in functions. If you are trying to recreate a CREATE TYPE statement, then you will need to check the sys.assembly_types DMV.
Also, to learn more about working with SQLCLR in general, please see the series of articles I am writing on this topic on SQL Server Central: Stairway to SQLCLR (free registration is required to read their content).

Sql Server: all object dependencies

Is there any place where I can find all possible object type dependencies in Sql Server?
What I mean by "object dependency" is a list of object that one object can depend on. For example, TABLE can depend on SCHEMA, TYPE, TABLE, FUNCTION, etc.
Aside from dynamic SQL, technically, SQL Server does keep track of dependencies. However, until SQL Server 2008, its tracking was not reliable because it only updated dependencies if all dependent entities existed at time of creation. SQL Server 2008 significantly improved dependency tracking.
In SQL Server 2000 and 2005, you can query against sys.sql_dependencies to get a list of dependencies.
In SQL Server 2008, you should use sys.sql_expression_dependencies See sys.sql_expression_dependencies for more.
EDIT I think I may have misinterpreted your question. It sounds like you are looking for a list of object types on which a TABLE type object can depend. Directly or indirectly, it would be any object type in the system. If we only want "direct" dependencies, then it depends on what is meant by "direct". For example, does a trigger that references a view count as a direct dependency of the trigger table to the view?
EDIT As far as I know, there is no enumerated list of all possible dependencies between types. The best that you could achieve is to analyze the types that do depend on other types in a given database using something like:
Select DependentObj.Type, ReferencedObj.Type
from sys.sql_dependencies As D
Join sys.sysobjects As ReferencedObj
On ReferencedObj.id = D.referenced_major_id
Join sys.sysobjects As DependentObj
On DependentObj.id = D.object_id
Group By DependentObj.Type, ReferencedObj.Type
For actual objects (what objects does table 'foo' depend on):
sys.sql_dependencies
Is mostly accurate. There is also the SMO helper, DependencyWalker.
As a general type question (ie. what type of objects can a table depend on), you just need to go through the spec on MSDN for each object CREATE/ALTER statement and read carefully everything.
A persisted computed column in a table could depend on a user defined function.
A non-deterministic user-defined function can depend on a table.
A constraint could cause a table to depend on a table.
ad nauseum.
You could pick any pair of object types and we might be able to come up with a dependency.
There are obviously some restrictions in the various SQL Server features, but I'm not aware of any comprehensive matrix of all possible allowed and disallowed dependencies.

Resources