2010-10-22 57 views
1

我有一个存储过程,由数据收集系统调用。使用动态SQL访问存储过程参数

该过程有许多参数用于收集数据。

我使用INFORMATION_SCHEMA参数列表拉到一个临时表

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

从那里我可以插入我的标签列表表

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

任何丢失的数据的标签名称到目前为止这么好,现在我想使用ToolTag和临时表列表来插入每个参数的数据。最初我通过一些动态SQL可以做到这一点。

 
    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 

当然以上不作为@sql声明的工作结束了这样的事情:

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

由于与@ShutterPosition参数值相反。我被困在这里,我可以对每个名字进行某种强制性的操作,但是我希望能够抽象并且对其他程序具有可重用性。

那么有没有什么出路,或者我用这种方法吠叫错误的树?

编辑: 我的模式是这样的: alt text

的目标是插入一条记录到ToolTagData数据为每个存储过程的参数。 ToolTag的关键是存储过程参数的名称。

希望通过向过程添加新参数将标签添加到ToolTag表中。

我受限于第三方数据采集程序能做什么,所以这次尝试抽象了这个过程。

+0

你在吠叫错误的树。给我们一些关于你的功能意图的信息,你会得到一些更好的建议。 – Tahbaza 2010-10-22 23:11:44

+0

这里有一些更多的细节 – dverespey 2010-10-22 23:30:16

回答

0

最终我决定使用CLR存储过程来实现这一点:

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

相反的EXEC,使用sp_ExecuteSQL

然后,你可以做这样的事情:

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


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

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