2010-10-22 5 views
1

J'ai une procédure stockée qui est appelée par la collecte de données système.Accès aux paramètres de procédure stockée avec SQL dynamique

La procédure comporte de nombreux paramètres pour les données collectées.

J'utilise le INFORMATION_SCHEMA pour tirer la liste des paramètres dans une table temporaire

 
    SELECT substring(PARAMETER_NAME , 2 , len(PARAMETER_NAME) - 1) 'SpParam', PARAMETER_NAME, DATA_TYPE 
    INTO #tempParam 
    FROM INFORMATION_SCHEMA.PARAMETERS 
    WHERE SPECIFIC_NAME='InsertB2ChamberData' 

De là, je peux insérer les noms de balise de données manquantes dans ma table de liste de tags

 
    INSERT INTO ToolTag 
    SELECT @ToolID, @ToolTagTypeID, SpParam, 'Default Description', GETDATE() 
    FROM #tempParam 
    WHERE spParam NOT IN (SELECT ToolTagName FROM ToolTag WHERE ToolID = @ToolID) 

Jusqu'à présent si bon, maintenant je voudrais utiliser le ToolTag et la liste de la table temporaire pour insérer les données de chaque paramètre. Initialement je pensais que du SQL dynamique ferait l'affaire.

 
    DECLARE tag CURSOR FOR 
    SELECT t.ToolTagID, p.PARAMETER_NAME, p.DATA_TYPE 
    FROM ToolTag t 
     JOIN #tempParam p 
      ON t.ToolTagName = p.SpParam 

    OPEN tag 

    FETCH NEXT FROM tag INTO @TagID, @Parameter, @DataType 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 

     SELECT @Cindex = CHARINDEX('char', @DataType) 
     IF @Cindex 0 
     begin 

      SELECT @sql = 
      N'INSERT INTO ToolTagData VALUES('+convert(varchar(10),@TagID)+', '+convert(varchar(10),@ToolDataEventID)+', '+ @Parameter +', 0)' 
     end 
     else 
     begin 
      SELECT @sql = 
      N'INSERT INTO ToolTagData VALUES('+convert(varchar(10),@TagID)+', '+convert(varchar(10),@ToolDataEventID)+', CONVERT(varchar(255),'[email protected] +'), '+convert(varchar(50),@Parameter)+')' 

     end 

     EXEC(@sql) 

     FETCH NEXT FROM tag INTO @TagID, @Parameter, @DataType 
    END 

    CLOSE tag 
    DEALLOCATE tag 

Bien sûr, le travail ne pas ci-dessus la déclaration @sql se retrouve avec quelque chose comme ceci:

INSERT INTO ToolTagData (315, 50, @ShutterPosition, 0)

Comme opposé à la valeur du paramètre @ShutterPosition. Je suis coincé ici, je pourrais donc avoir une sorte de force brute avec chaque nom, mais j'aimerais pouvoir être abstrait et être réutilisable pour d'autres procédures.

Y a-t-il un moyen de contourner cela, ou est-ce que j'aboie le mauvais arbre avec cette approche?

EDIT: Mon schéma ressemble à ceci: alt text

Le but est d'insérer un enregistrement dans les données ToolTagData pour chaque paramètre de procédure stockée. La clé dans ToolTag est le nom du paramètre de procédure stockée.

L'espoir est que les balises soient ajoutées à la table ToolTag simplement en ajoutant un nouveau paramètre à la procédure.

Je suis limité par ce que le programme d'acquisition de données tiers peut faire, donc c'est une tentative d'abstraction du processus.

+0

Vous aboyez dans le mauvais arbre. Donnez-nous plus d'informations sur votre intention fonctionnelle et vous obtiendrez de meilleures suggestions. – Tahbaza

+0

Voici plus de détails – dverespey

Répondre

0

En fin de compte, je l'ai décidé d'utiliser une procédure stockée CLR pour mettre en œuvre ceci:

var tags = new 
              { 
                @Tag1, 
                @Tag2, 
                ... 
                @LastTag}; 

      using (var conn = 
         new SqlConnection("context connection = true")) 
      { 
         conn.Open(); 
         var cmd = new SqlCommand 
                { 
                  Connection = conn, 
                  CommandText = 
                    "INSERT INTO TagGroupData SELECT TagGroupID , GETDATE() FROM TagGroup WHERE TagGroupName = 'L1Data' SELECT SCOPE_IDENTITY()" 
                }; 

         var tagGroupDataId = cmd.ExecuteScalar(); 

         cmd.CommandText = ""; 


         cmd.Parameters.Add("@Data", SqlDbType.Float); 
         cmd.Parameters.Add("@Name", SqlDbType.VarChar, 100); 
         cmd.Parameters.Add("@tg", SqlDbType.Int); 

         cmd.Parameters[2].Value = tagGroupDataId; 

         cmd.CommandText = 
           "INSERT INTO ToolTagData SELECT t.ToolTagID, CONVERT(varchar(255),@Data), @Data, @tg, GETDATE() FROM ToolTag t WHERE t.ToolTagName = @Name"; 

         foreach (PropertyInfo pi in tags.GetType().GetProperties()) 
         { 
           cmd.Parameters[1].Value = pi.Name; 
           cmd.Parameters[0].Value = pi.GetValue(tags, null); 

           cmd.ExecuteScalar(); 
         } 
1

Au lieu de EXEC, utilisez sp_ExecuteSQL

Ensuite, vous pouvez faire quelque chose comme ceci:

DECLARE 
    @sql nvarchar(max), 
    @ParamDef nvarchar(1000) 


SET @ParamDef = N'@param1 int, 
    @param2 int' 

EXECUTE dbo.sp_ExecuteSQL @sql, @ParamDef, 
    @param1 = @param1, 
    @param2 = @param2 
Questions connexes