Is there a way to determine programmatically if a SQL Server stored procedure parameter has a default? (Bonus points if you can determine what the default is.) SqlCommandB
This is the SMO answer in PowerShell:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null
$srv = New-Object "Microsoft.SqlServer.Management.Smo.Server" "MyServer\MyInstance"
$db = $srv.Databases["MyDatabase"];
$proc = $db.StoredProcedures["MyStoredProcedure"]
foreach($parameter in $proc.Parameters) {
if ($parameter.DefaultValue){
Write-Host "$proc , $parameter , $($parameter.DefaultValue)"
}
else{
Write-Host "$proc , $parameter , No Default Value"
}
}
This is kind of a hack, but you could always just give optional parameters a special name like:
@AgeOptional = 15
...then write a simple method that checks a parameter to see if it's optional. Not ideal, but given the situation, it might actually be a decent solution.
I found a way using SMO:
Server srv;
srv = new Server("ServerName");
Database db;
db = srv.Databases["MyDatabase"];
var Params = db.StoredProcedures["MyStoredProc"].Parameters;
foreach(StoredProcedureParameter param in Params) {
Console.WriteLine(param.Name + "-" + param.DefaultValue);
}
For stored procedures, I believe you would have to write something that parses T-SQL, or use the T-SQL parser that Microsoft provides.
The parser and script generator live in two assemblies. The
Microsoft.Data.Schema.ScriptDom
contains provider agnostic classes and theMicrosoft.Data.Schema.ScriptDom.Sql
assembly contain classes for the parser and script generator that are SQL Server specific.
How to specifically use this to identify the parameters and whether they're defaulted isn't covered and would be something you'd have to work on (probably with a deal of effort) using the sample code.
Run the builtin sp_help stored procedure?
Not a big deal in SQL Server 2005 and up:
SELECT
pa.NAME,
t.name 'Type',
pa.max_length,
pa.has_default_value,
pa.default_value
FROM
sys.parameters pa
INNER JOIN
sys.procedures pr ON pa.object_id = pr.object_id
INNER JOIN
sys.types t ON pa.system_type_id = t.system_type_id
WHERE
pr.Name = 'YourStoredProcName'
Unfortunately, even though this seemed like a piece of cake - it doesn't work :-(
From Technet:
SQL Server only maintains default values for CLR objects in this catalog view; therefore, this column has a value of 0 for Transact-SQL objects. To view the default value of a parameter in a Transact-SQL object, query the definition column of the sys.sql_modules catalog view, or use the OBJECT_DEFINITION system function.
So all you can do is either query sys.sql_modules
or call SELECT object_definition(object_id)
to basically get the SQL definition (the T-SQL source code) for your stored proc and then you'd need to parse that (sucks!! big time.....)
Seems like there's really no other way to do this ... I'm amazed and appaled.....
Maybe in SQL Server 2008 R2 ? :-) Marc