Доступ к параметрам хранимой процедуры с помощью динамического SQL - PullRequest
1 голос
/ 23 октября 2010

У меня есть хранимая процедура, которая вызывается при сборе данных system .

Процедура имеет много параметров, которые для собранных данных.

Я использую 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),'+@Parameter +'), '+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. Я застрял здесь, я мог бы использовать какую-то грубую силу с каждым именем, но я хотел бы быть в состоянии абстрагироваться и использовать повторно для других процедур.

Так есть ли какой-то выход из этого, или я лаю не на том дереве с таким подходом?

EDIT: Моя схема выглядит так: alt text

Цель состоит в том, чтобы вставить одну запись в Данные ToolTagData для каждого параметра хранимой процедуры. Ключ в ToolTag - это имя параметра хранимой процедуры.

Надеемся, что теги будут добавлены в таблицу ToolTag, просто добавив новый параметр в процедуру.

Я ограничен возможностями сторонней программы сбора данных, поэтому это попытка абстрагировать процесс.

Ответы [ 2 ]

1 голос
/ 23 октября 2010

Вместо 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
0 голосов
/ 11 января 2011

В конце я решил использовать хранимую процедуру 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();
                      }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...