2016-05-05 15 views
4

Ich habe einen Proc, der einen Web Service-Aufruf bedient. Dies ist eine SQL 2012-Umgebung. Der Prozess verwendet einen Namen für eine gespeicherte Prozedur und einen beliebigen Satz von Prozedurparametern (getrennt durch ein Trennzeichen für Zeichenfolgen). Innerhalb des Procs baue ich die Anweisung wie folgt: -Gespeicherte Prozedur Default Parameter Identification

INSERT INTO @Params 
    SELECT p.parameter_id, p.name AS ParameterName, t.name AS ParameterType, p.max_length AS ParameterLength, '' 
    FROM sys.parameters AS p 
    JOIN sys.types AS t ON t.user_type_id = p.user_type_id 
    WHERE object_id = OBJECT_ID(RTRIM(LTRIM(@ProcName))) 

    UPDATE P 
    SET pValue = s.data 
    FROM dbo.split(@ParamList,'ç') as S 
    INNER JOIN @Params as P ON P.id = S.ID 


    SELECT @ParamSplit = ISNULL(Stuff((SELECT ',' + 
     pName + '=' + 
     CASE 
      WHEN pValue = 'ÆNULL' THEN 'NULL' 
      WHEN pType = 'varchar' THEN char(39) + replace(pValue,char(39),char(39) + char(39)) + char(39) 
      WHEN pType = 'date' THEN char(39) + replace(pValue,char(39),char(39) + char(39)) + char(39) 
      WHEN pType = 'datetime' or pType='TIME' THEN char(39) + replace(pValue,char(39),char(39) + char(39)) + char(39) 
      else pValue 
      END 
    FROM @Params 
    FOR XML PATH ('')),1,1,''),'') 

Dies funktioniert gut. Ich weiß zu schätzen, dass nicht alle Datentypen geprüft werden, aber für meine Zwecke (dies ist ein geschlossenes System) deckt es alle erforderlichen Grundlagen ab. Aber ich habe ein Problem, da der aufrufende Dienst ALLE Parameter übergeben muss, sogar Parameter, die innerhalb des proc möglicherweise voreingestellt sind.

Es gibt ein Feld, das

und ein weiteres Feld

default_value

, aber die Überprüfung der Microsoft

has_default_value ist in der sys.parameters Tabelle ist Dokumentation sie sagen: -

Standardwerte werden in der sys.parameters.default Spalte nur für CLR Verfahren aufgezeichnet. Diese Spalte ist NULL für Transact-SQL Prozedurparameter.

Was würde Ich mag zu tun ist, zu identifizieren, wenn die proc Ich rufe alle Standard Parameter hat, wenn sie es tun (und der Telefonie-Dienst hat sie nicht bestanden) ich die Standardeinstellungen verwenden, sonst können diese ersetzt werden durch was auch immer der anrufende Dienst passiert hat.

Also ... Frage - weiß jemand, wie man erkennt, wenn der Proc irgendwelche Standardparameter zugewiesen hat?

+1

Die Antworten auf [Diese Frage] (http://stackoverflow.com/q/5873731/1048425) enthält eine Möglichkeit, die Prozedurdefinition zu analysieren, um die Standardwerte abzurufen. Ich bin mir nicht sicher, ob es einen saubereren Weg gibt. – GarethD

+1

Sie könnten: 1) Erstellen DDL-Trigger, die 'CREATE/ALTER-Prozedur abfangen wird 2) Parse-Definition zum Abrufen von Standardwerten 3) Fügen Sie erweiterte Eigenschaften 4) In Ihrem Code Liste alle Parameter aus' sys.parameters' und holen Sie Standardwerte von längeren Ereignissen. So etwas wie ** [demo] (http://rextester.com/GGXWTY28224) **. Es ist durchaus möglich, dies auf automatisierte Weise zu erreichen. Das Parsen könnte noch einfacher sein, wenn Sie eine Dokumentation im 'JSON/XML-Format' als Kommentar haben. – lad2025

+0

Dies ist eine bestehende, Produktions-DB, also nicht wirklich praktisch, um die Motorhaube zu öffnen. Ich kann abfragen, was da ist - kann keine Procs wirklich ändern. Ich denke, das Analysieren zur Laufzeit wäre ineffizient (diese Procs werden oft, oft in der Sekunde genannt). Ich dachte, was ich könnte ist davon auszugehen, dass, wenn der Web-Service hat nicht alle Parameter übergeben, dann alle verpasst müssen durch die defaut - so kann der Proc ohne diese Parameter aufgerufen werden. Ich denke, das wird funktionieren ... –

Antwort

0

du versuchen können, müssen aber möglicherweise Format Ihrer gespeicherten Prozedur defintions überprüfen, können Sie diese anrufen aus Ihrer Anwendung und Cache auf der Client-Seite kann der Lage sein, die Leistung Treffer zu verhindern:

Declare @ProcedureName VARCHAR(50) = 'MySP' 
DECLARE @text VARCHAR(MAX) 
DECLARE @startPos int = 0 
DECLARE @endPos int = 0 

SELECT @text=text FROM syscomments 
WHERE id = object_id(@ProcedureName) and colid=1 AND text LIKE '%(%' 

IF @text IS NULL 
BEGIN 
    -- No Parameters in stored procedure 
    PRINT 'No Parameters' 
END 
ELSE 
BEGIN 

    -- Find Start of parameter declaration 
    SELECT @startPos = PATINDEX('%(%' ,@text) 
    -- Find end of parameter declaration 
    SELECT @endPos = PATINDEX('%AS' + CHAR(13) + '%' ,@text) 

    -- Set Text to our parameters string 
    SELECT @text = SUBSTRING(@text, @startPos + 1, @endpos - @startpos -4) 

    -- Split parameters and insert into table 
    -- Alternatively use other string splitting techniques such as numbers table 
    DECLARE @t1 TABLE (id INT IDENTITY(1,1), val NVARCHAR(MAX)) 
    DECLARE @xml XML 
    SET @xml = N'<t>' + REPLACE(@text,',','</t><t>') + '</t>' 
    INSERT INTO @t1(val) 
    SELECT r.value('.','varchar(MAX)') as item 
    FROM @xml.nodes('/t') as records(r) 


    SELECT SUBSTRING(val, PATINDEX('%@%', val), PATINDEX('% %', val) - PATINDEX('%@%', val)) as Parm, 
      SUBSTRING(val, PATINDEX('%=%',val) + 1, DATALENGTH(val) - PATINDEX('%=%',val)) As DefaultValue 
    FROM @t1 
    WHERE val like '%=%' -- Only get parameters with default value 

END