2016-05-15 43 views
0

我有一個名爲ReportValues的表,它存儲關於鍵和值對中的球員的所有信息。表中有一個來自另一個名爲Reports的表的外鍵,我試圖爲每個報表獲取所有數據,其中鍵爲列名,值將填充返回的表。 @pID手動,而不是作爲參數,然後代碼工作,但是當使用參數我得到以下錯誤:「必須聲明標量變量」@ PID「。這裏是我的代碼:試圖從asp.net傳遞參數,當使用DECLARE語句,但得到一個錯誤說:「必須聲明標量變量」@pID「

public DataTable getBarChartData(int p_ID)   
{ 
    //this query is transposing rows into columns as each key gets a column and the grouping variable is RV.report 
    string sqlQuery = "DECLARE @keyName AS VARCHAR(MAX) "; 
    sqlQuery += "SELECT @keyName = "; 
    sqlQuery += "COALESCE(@keyName + ', ', '') + CAST(keyName AS VARCHAR(20)) "; 
    sqlQuery += "FROM(SELECT DISTINCT keyname FROM ReportValues) ActivePlayers "; 
    sqlQuery += "SELECT @keyName keyNames "; 
    sqlQuery += "DECLARE @DynamicPIVOT AS VARCHAR(MAX) "; 
    sqlQuery += "SELECT @DynamicPIVOT = 'SELECT ' + @keyName + "; 
    sqlQuery += "' FROM ("; 
    sqlQuery += "SELECT RV.report, RV.keyname, RV.value FROM ReportValues RV "; 
    sqlQuery += "join ReportValues RV1 on RV.report = RV1.report "; 
    sqlQuery += "join ReportValues RV2 on RV.report = RV2.report "; 
    sqlQuery += "where RV1.value <> 1 and RV1.keyName = ''SessionStage'' and RV2.value = @pID and RV2.keyName = ''PId'' and RV.report in ("; 
    sqlQuery += "SELECT id FROM Reports r "; 
    sqlQuery += "WHERE r.timeStamp >= dateadd(hour, -240, GETDATE()) "; 
    sqlQuery += ") "; 
    sqlQuery += ") ActivePlayers"; 
    sqlQuery += "PIVOT("; 
    sqlQuery += "MAX(value) FOR keyname IN(' + @keyName + ') "; 
    sqlQuery += ") Result; ' "; 
    sqlQuery += "EXEC(@DynamicPIVOT) "; 
    int pID = p_ID; 
    //this passes the query and param to an execution function 
    DataTable dtLabels = GetBarChartDataByUser(sqlQuery, pID); 
    return dtLabels; 
} 

//this is the sql execution function 
public DataTable GetBarChartDataByUser(string strQuery, int pID) 
{ 
    SqlConnection con = new SqlConnection(createConnectionReadOnly()); 
    con.Open(); 
    try 
    { 

     SqlCommand cmd = con.CreateCommand(); 
     cmd.CommandType = CommandType.Text; 
     cmd.CommandText = strQuery; 
     cmd.Parameters.AddWithValue("@pID", pID); 
     SqlDataAdapter dap = new SqlDataAdapter(cmd); 
     //here is where I get the error 
     DataSet ds = new DataSet(); 
     dap.Fill(ds); 
     return ds.Tables[0]; 
    } 
    catch (Exception ex) 
    { 

    } 
    finally 
    { 
     if (con.State == ConnectionState.Open) 
     { 
      con.Close(); 
     } 
    } 
    return null; 

} 
+0

我不認爲你可以像這樣將變量傳遞給exec。你應該嘗試sp_executesql而不是 –

+0

這個問題與sp_executesql無關 – Alex

回答

1

「和RV2.value = @pID」是一個動態的字符串的一部分,而不是視爲動態字符串建築查詢的變量。在SQL Server中,變量作用域只擴展到當前正在執行的批處理或函數,因此在「EXEC()」內執行的動態構建的代碼不知道變量@pID。
你能解決這個問題有幾種方法,其中之一是以下:

sqlQuery += "join ReportValues RV2 on RV.report = RV2.report "; 
sqlQuery += "where RV1.value <> 1 and RV1.keyName = ''SessionStage'' and RV2.value = @pID and RV2.keyName = ''PId'' and RV.report in ("; 
sqlQuery += "SELECT id FROM Reports r "; 

sqlQuery += "join ReportValues RV2 on RV.report = RV2.report "; 
sqlQuery += "where RV1.value <> 1 and RV1.keyName = ''SessionStage'' and RV2.value = ' + CONVERT(VARCHAR, @pID) + ' and RV2.keyName = ''PId'' and RV.report in ("; 
sqlQuery += "SELECT id FROM Reports r "; 

(通知 '+ @pID +')

另一個(我會爭辯更好的辦法)是取代:

"EXEC(@DynamicPIVOT) " 

"EXEC sp_executesql @DynamicPIVOT, N'@pID INT', @pID " 

注: @DynamicPIVOT必須被聲明爲NVARCHAR(MAX)
注2: DECLARE @pID是相同的數據類型RV2.keyName。這將避免查詢執行期間的類型轉換

爲了幫助診斷未來的類似問題,我建議您在執行sqlQuery之前檢查其值,並將其粘貼到SQL Management Studio中。 這將清楚哪些部分是字符串,哪些部分是SQL可執行代碼。

+0

我試過這個,但它沒有工作。我創建了一個存儲過程,而它確實工作。這樣做有風險嗎? – Orensig

+0

如果你的意思是創建程序,那麼沒有,沒有風險。 – Alex

+0

你能詳細說明哪些不適合你嗎? – Alex

相關問題