将SQL Server查询转换为C#动态查询失败

时间:2018-06-20 15:20:38

标签: c# sql sql-server

我有一个SQL Server查询,可以很好地作为存储过程使用:

CREATE PROCEDURE "InputData_GetStatus" 
     @id VARCHAR(250) 
AS 
BEGIN 
    SET NOCOUNT ON;

    DECLARE @lookingFor NVARCHAR(36);

    SELECT @lookingFor = CONVERT(NVARCHAR(36),  (SELECT TOP 1(UID) 
                                                 FROM StudyInput 
                                                 WHERE ID = @id));
    IF (@lookingFor IS NULL)
        RETURN;

    DECLARE @query NVARCHAR(2000);
    SET @query = 'select null as InUID, OutUID, InNext, Status, ''StudyInput'' as TableName from StudyInput_InOut where OutUID = ''' + @lookingFor + '''';

    DECLARE @stepName VARCHAR(150);
    DECLARE @processUID uniqueidentifier;

    DECLARE MY_CURSOR CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR
        SELECT stepName, ProcessUID 
        FROM StudyInput_DirectLink 
        WHERE InputUID = @lookingFor 


    OPEN MY_CURSOR 

    FETCH NEXT FROM MY_CURSOR INTO @stepName, @processUID 

    WHILE @@FETCH_STATUS = 0 
    BEGIN
        SET @query = @query + ' union all ';
        SET @query = @query + 'select InUID, OutUID, InNext, Status, ''' + @stepName + ''' as TableName from ' + @stepName + '_InOut where OutUID = ''' + convert(nvarchar(36), @processUID) + '''';

        FETCH NEXT FROM MY_CURSOR INTO @stepName, @processUID;
    END 

    CLOSE MY_CURSOR;
    DEALLOCATE MY_CURSOR;

    EXECUTE sp_executesql @query;
END

在C#中,我编写了使用动态表和存储过程动态创建数据库的代码。

我试图将上面的查询转换为字符串,每次创建数据库时都可以执行以将其创建为存储过程。

但是我的格式似乎有误,因为我不断收到以下错误(或其他错误)

  

''附近的语法不正确。
  '+ @stepName +'附近的语法不正确。

这就是我现在在C#中查询的内容

private void SetupOtherQueries()
{
  string query = "";

  query += "declare @lookingFor nvarchar(36);";

  // Search for the UID of the InputKey associated to the Data Input we want to query the status for
  query += string.Format(" select @lookingFor = convert(nvarchar(36), (select top 1(UID) from StudyInput where {0} = @id));", this._config.InputKey);
  query += " if (@lookingFor is null) return;";

  query += " DECLARE @query NVARCHAR(MAX);";

  // Build a dynamic query to get the status of the data for each step it has been involved with
  // Starting with StudyInput
  query += " set @query = 'select null as InUID, OutUID, InNext, Status, ''StudyInput'' as TableName from StudyInput_InOut where OutUID = ''' + @lookingFor + '''';";

  // Get all the direct links involving the Data
  // And build a dynamic query for each Step table
  query += " SELECT @query = COALESCE(@query + ' union all select InUID, OutUID, InNext, Status, ''' + stepName + ''' as TableName from ' + stepName + '_InOut where OutUID = ''' + convert(nvarchar(36), ProcessUID) + '''', '')";
  query += " FROM StudyInput_DirectLink";
  query += " where InputUID = @lookingFor";

  // Execute the dynamic query
  query += " EXECUTE sp_executesql @query;";

  DB_Helpers.CreateStoredProcedure(
    this._config.StudyName,
    "InputData_GetStatus",
    String.Format("@id varchar({0})", MaxFieldSize),
    query);
}

助手功能:

static public void CreateStoredProcedure(
  string db,
  string queryName,
  string parameters,
  string procedure)
{
  ExecuteQuery(
    db,
    String.Format("if exists(Select * from sysobjects where name = '{0}')  begin drop procedure {0} end; EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE [{0}] {1} AS BEGIN SET NOCOUNT ON; {2}; END'",
      queryName,
      parameters,
      procedure));
}

static public void ExecuteQuery(
  string db,
  string query)
{
  SqlConnection connection = null;
  try
  {
    connection = new SqlConnection(string.Format(connectionString, db));
    connection.Open();

    // Creates DB
    using (SqlCommand command = new SqlCommand(query, connection))
    {
      command.ExecuteNonQuery();
    }
  }
  catch (Exception ex)
  {
    throw ex;
  }
  finally
  {
    connection.Close();
  }
}

我很确定问题归结为构建查询字符串时所需的'。

但是我只是想不出我需要多少才能正确格式化它。

编辑:

这是执行之前的完整查询:

if exists(Select * from sysobjects where name = 'InputData_GetStatus')
begin drop procedure InputData_GetStatus end;
EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE [InputData_GetStatus] @id varchar(250) AS BEGIN SET NOCOUNT ON; declare @lookingFor nvarchar(36); select @lookingFor = convert(nvarchar(36), (select top 1(UID) from StudyInput where MINC = @id)); if (@lookingFor is null) return; DECLARE @query NVARCHAR(MAX); set @query = 'select null as InUID, OutUID, InNext, Status, ''StudyInput'' as TableName from StudyInput_InOut where OutUID = ''' + @lookingFor + ''''; SELECT @query = COALESCE(@query + ' union all select InUID, OutUID, InNext, Status, ''' + stepName + ''' as TableName from ' + stepName + '_InOut where OutUID = ''' + convert(nvarchar(36), ProcessUID) + '''', '') FROM StudyInput_DirectLink where InputUID = @lookingFor EXECUTE sp_executesql @query;; END'

1 个答案:

答案 0 :(得分:0)

最后,它运行了在执行之前生成的字符串查询的子集,然后每次添加更多内容并将输出与原始查询进行比较,就可以使它工作。

如果有人遇到相同的问题,需要在自己的查询中找出答案,我将在此处发布最终结果。

  string query = "";

  query += "declare @lookingFor nvarchar(36);";

  // Search for the UID of the InputKey associated to the Data Input we want to query the status for
  query += string.Format(" select @lookingFor = convert(nvarchar(36), (select top 1(UID) from StudyInput where {0} = @id));", this._config.InputKey);
  query += " if (@lookingFor is null) return;";

  query += " DECLARE @query NVARCHAR(MAX);";

  // Build a dynamic query to get the status of the data for each step it has been involved with
  // Starting with StudyInput
  query += " set @query = ''select null as InUID, OutUID, InNext, Status, ''''StudyInput'''' as TableName from StudyInput_InOut where OutUID = '''''' + @lookingFor + '''''''';";

  // Get all the direct links involving the Data
  // And build a dynamic query for each Step table
  query += " SELECT @query = COALESCE(@query + '' union all select InUID, OutUID, InNext, Status, '''''' + stepName + '''''' as TableName from '' + stepName + ''_InOut where OutUID = '''''' + convert(nvarchar(36), ProcessUID) + '''''''', '''')";
  query += " FROM StudyInput_DirectLink";
  query += " where InputUID = @lookingFor;";

  // Execute the dynamic query
  query += " EXECUTE sp_executesql @query;";