0

のデフォルト値を取得します。私は、デフォルト値でストアドプロシージャの下に作成しました:ストアドプロシージャパラメータ

CREATE PROCEDURE [dbo].[Sample1] 
    @OrderID INT = 10285 
AS 
    SELECT ProductName, OrderID 
    FROM Products P, [Order Details] Od 
    WHERE Od.ProductID = P.ProductID 
     AND Od.OrderID = @OrderID 

sys.parametersを使用してパラメータのデフォルト値(10285)を取得しようとしました。

Select a.object_id, a.default_value 
from sys.parameters a 
inner join sys.types b on b.system_type_id = a.system_type_id 
where Object_id = object_id('[dbo].[Sample1]') 

しかし、私はdefault_valueとして10285を期待していた間、私は、default_valueとしてNULLました。

デフォルト値を取得する方法はありますか?

+0

[悪い習慣をキックする:古いスタイルを使用してJOINを](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old ANSI - ** 92 ** SQL標準(** 25年*)の*適切な* ANSI 'JOIN'構文で置き換えられた*スタイルのコンマで区切られたテーブル* *前)、その使用は推奨されません –

答えて

0

これは、デフォルト値が存在するかではない特定のパラメータであり、場合でも、パラメータのデフォルト値を見つけるために何の些細な方法はありませんMicrosoft has neglected this topicこととなります。

我々はすべて知っているように、T-SQLストアドプロシージャは、パラメータのデフォルト値は、sys.parameters、all_parameters、system_parametersに格納されている ではありません。また、 は、sp_sproc_columns、sys.columns、または sp_procedure_params_rowsetによって公開されません。

マイクロソフトからのフィードバック:

SQL Serverが唯一 このカタログビューでCLRオブジェクトのデフォルト値を維持」というティボーKaraszi、BOLの文書が掲示するとおり、 そのため、この列には値を持っています0 Transact-SQLオブジェクトの場合 Transact-SQLオブジェクトのパラメータの既定値を表示するには、 sys.sql_modulesカタログビューの定義列を照会するか、 OBJECT_DEFINITIONシステム関数を使用してください。

ユーコンでは、パラメータがデフォルトで の値であることもビットを保存しません。

私は、最初のコードスニペットin this answerをテストしてきたし、それはあなたの簡単な例のために働くようだ:

SELECT 
     data3.name 
    , [default_value] = REVERSE(RTRIM(SUBSTRING(
      data3.rtoken 
     , CASE 
      WHEN CHARINDEX(N',', data3.rtoken) > 0 
       THEN CHARINDEX(N',', data3.rtoken) + 1 
      WHEN CHARINDEX(N')', data3.rtoken) > 0 
       THEN CHARINDEX(N')', data3.rtoken) + 1 
      ELSE 1 
      END 
     , LEN(data3.rtoken) 
    ))) 
FROM (
    SELECT 
      data2.name 
     , rtoken = REVERSE(
      SUBSTRING(ptoken 
        , CHARINDEX('=', ptoken, 1) + 1 
        , LEN(data2.ptoken)) 
       ) 
    FROM (
     SELECT 
       data.name 
      , ptoken = SUBSTRING(
        data.tokens 
       , token_pos + name_length + 1 
       , ISNULL(ABS(next_token_pos - token_pos - name_length - 1), LEN(data.tokens)) 
      ) 
     FROM (
      SELECT 
        sm3.tokens 
       , p.name 
       , name_length = LEN(p.name) 
       , token_pos = CHARINDEX(p.name, sm3.tokens) 
       , next_token_pos = CHARINDEX(p2.name, sm3.tokens) 
      FROM (
       SELECT 
         sm2.[object_id] 
        , sm2.[type] 
        , tokens = REVERSE(SUBSTRING(sm2.tokens, ISNULL(CHARINDEX('SA', sm2.tokens) + 2, 0), LEN(sm2.tokens))) 
       FROM (
        SELECT 
          sm.[object_id] 
         , o.[type] 
         , tokens = REVERSE(SUBSTRING(
             sm.[definition] 
            , CHARINDEX(o.name, sm.[definition]) + LEN(o.name) + 1 
            , ABS(CHARINDEX(N'AS', sm.[definition])) 
           ) 
         ) 
        FROM sys.sql_modules sm WITH (NOLOCK) 
        JOIN sys.objects o WITH (NOLOCK) ON sm.[object_id] = o.[object_id] 
        JOIN sys.schemas s WITH (NOLOCK) ON o.[schema_id] = s.[schema_id] 
        WHERE o.[type] = 'P ' 
         AND s.name + '.' + o.name = 'dbo.Sample1' 
       ) sm2 
       WHERE sm2.tokens LIKE '%=%' 
      ) sm3 
      JOIN sys.parameters p WITH (NOLOCK) ON sm3.[object_id] = p.[object_id] 
      OUTER APPLY (
       SELECT p2.name 
       FROM sys.parameters p2 WITH (NOLOCK) 
       WHERE p2.is_output = 0 
        AND sm3.[object_id] = p2.[object_id] 
        AND p.parameter_id + 1 = p2.parameter_id 
      ) p2 
      WHERE p.is_output = 0 
     ) data 
    ) data2 
    WHERE data2.ptoken LIKE '%=%' 
) data3 

しかし、それは1つが簡単にシステムのビューから照会可能されることを想定していたタスクのために本当に醜いです。

0

デフォルトのストアドプロシージャのパラメータ値は、SQL Serverカタログビューを介して公開する必要があることに同意します。

T-SQL解析メソッドは多くの場合に機能しますが、脆弱です。 TransactSQL ScriptDOMの使用を検討してください。以下は、PowerShellとC#の組み合わせを使用した例です。これはすべてのケースで完璧になるとは言いませんが、私が投げたすべてのパラメータを処理するようです。

この例では、SSMSインストールのMicrosoft.SqlServer.TransactSql.ScriptDom.dllアセンブリを使用しましたが、NuGet Galleryからダウンロードできます。

try 
{ 
    Add-type -LiteralPath @("C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio\Extensions\Application\Microsoft.SqlServer.TransactSql.ScriptDom.dll"); 
    Add-type ` 
     -ReferencedAssemblies @("C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio\Extensions\Application\Microsoft.SqlServer.TransactSql.ScriptDom.dll") ` 
     -TypeDefinition @" 
using System; 
using System.Collections.Generic; 
using System.Text; 
using Microsoft.SqlServer.TransactSql.ScriptDom; 
using System.IO; 
public static class ProcParser 
{ 

    public static List<StoredProcedureParameter> GetStoredProcedureParameters(string storedProcedureDefinition) 
    { 

     StringReader reader = new StringReader(storedProcedureDefinition); 
     var parser = new TSql140Parser(true); 

     IList<ParseError> errors; 
     TSqlFragment sqlFragment = parser.Parse(reader, out errors); 

     if (errors.Count > 0) 
     { 
      throw new Exception(`"Error parsing stored procedure definition`"); 
     } 

     SQLVisitor sqlVisitor = new SQLVisitor(); 
     sqlFragment.Accept(sqlVisitor); 

     return sqlVisitor.StoredProcedureParameters; 

    } 

} 

internal class SQLVisitor : TSqlFragmentVisitor 
{ 

    public List<StoredProcedureParameter> StoredProcedureParameters = new List<StoredProcedureParameter>(); 

    public override void ExplicitVisit(ProcedureParameter node) 
    { 

     var p = StoredProcedureParameter.CreateProcedureParameter(node); 
     StoredProcedureParameters.Add(p); 

    } 

} 

public class StoredProcedureParameter 
{ 
    public string ParameterName; 
    public string ParameterType; 
    public string ParameterDirection = null; 
    public string DefaultParameterValue = null; 

    public static StoredProcedureParameter CreateProcedureParameter(ProcedureParameter node) 
    { 
     var param = new StoredProcedureParameter(); 

     //parameter name 
     param.ParameterName = node.VariableName.Value; 

     //data type 
     switch (((ParameterizedDataTypeReference)node.DataType).Parameters.Count) 
     { 
      case 0: 
       if (node.DataType.Name.Identifiers.Count == 1) 
       { 
        param.ParameterType = node.DataType.Name.Identifiers[0].Value; 
       } 
       else 
       { 
        //schema-qualified type name 
        param.ParameterType = node.DataType.Name.Identifiers[0].Value + `".`" + node.DataType.Name.Identifiers[1].Value; 
       } 
       break; 
      case 1: 
       param.ParameterType = node.DataType.Name.Identifiers[0].Value + "(" + ((ParameterizedDataTypeReference)node.DataType).Parameters[0].Value + ")"; 
       break; 
      case 2: 
       param.ParameterType = node.DataType.Name.Identifiers[0].Value + "(" + ((ParameterizedDataTypeReference)node.DataType).Parameters[0].Value + "," + ((ParameterizedDataTypeReference)node.DataType).Parameters[1].Value + ")"; 
       break; 
     } 

     //default value 
     if (node.Value != null) 
     { 
      param.DefaultParameterValue = node.ScriptTokenStream[node.LastTokenIndex].Text; 
     } 

     //direction 
     if (node.Modifier == ParameterModifier.Output) 
     { 
      param.ParameterDirection = `"OUTPUT`"; 
     } 
     else if (node.Modifier == ParameterModifier.ReadOnly) 
     { 
      param.ParameterDirection = `"READONLY`"; 
     } 
     else 
     { 
      param.ParameterDirection = `"INPUT`"; 
     } 

     return param; 

    } 

    public override string ToString() 
    { 

     var sb = new StringBuilder(); 
     sb.Append(ParameterName); 
     sb.Append(`" `"); 
     sb.Append(ParameterType); 
     if (DefaultParameterValue != null) 
     { 
      sb.Append(`" `"); 
      sb.Append(DefaultParameterValue); 
     } 
     sb.Append(`" `"); 
     sb.Append(ParameterDirection); 
     return sb.ToString(); 

    } 

} 
"@ 

} 
catch [System.Reflection.ReflectionTypeLoadException] 
{ 
    Write-Host "Message: $($_.Exception.Message)" 
    Write-Host "StackTrace: $($_.Exception.StackTrace)" 
    Write-Host "LoaderExceptions: $($_.Exception.LoaderExceptions)" 
    throw; 
} 

Function Get-ProcText($connectionString, $procName) 
{ 
    $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString); 
    $connection.Open(); 
    $command = New-Object System.Data.SqlClient.SqlCommand("SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID(@ProcName);", $connection); 
    $procNameParameter = $command.Parameters.Add((New-Object System.Data.SqlClient.SqlParameter("@ProcName", [System.Data.SqlDbType]::NVarChar, 261))); 
    $procNameParameter.Value = $procName; 
    $procText = $command.ExecuteScalar(); 
    $connection.Close(); 
    return $procText; 
} 

############ 
### main ### 
############ 
try { 

    # get proc text definition from database 
    $procText = Get-ProcText ` 
     -connectionString "Data Source=.;Initial Catalog=tempdb;Integrated Security=SSPI" ` 
     -procName "dbo.testproc"; 

    # parse parameters from proc text 
    $procParameters = [ProcParser]::GetStoredProcedureParameters($procText); 

    # display parameter values 
    foreach($procParameter in $procParameters) 
    { 
     Write-Host "ParameterName=$($procParameter.ParameterName)"; 
     Write-Host "`tParameterType=$($procParameter.ParameterType)"; 
     Write-Host "`tDefaultParameterValue=$($procParameter.DefaultParameterValue)"; 
     Write-Host "`tParameterDirection=$($procParameter.ParameterDirection)"; 
    } 

} 
catch { 
    throw; 
} 
関連する問題