2015-01-06 64 views
0

我正在嘗試使用存儲過程從SQL Server 2008 R2數據庫查詢數據。代碼執行時沒有錯誤,但沒有從查詢返回結果。當通過SQL Server Management Studio使用完全相同的參數調用相同的存儲過程時,數據將正確返回。我不知道什麼可能會導致這種情況,可能是SqlClient實現的特定情況?查詢返回兩個DateTime2值之間的所有數據;如果我使這些值分開足夠遠,則會返回數據。顯然這不是理想的行爲。SQL查詢和SqlClient操作之間的區別

C#代碼(startTime.HasValueendTime.HasValue在這種情況下是true):

if (conn.State == ConnectionState.Closed) 
{ 
    conn.Open(); 
} 

SqlCommand comm = conn.CreateCommand(); 
comm.CommandType = CommandType.StoredProcedure; 
comm.CommandText = "GetAllPropertyValues"; 

comm.Parameters.Add("@dataTypeName", SqlDbType.NVarChar).Value = dataTypeName; 
comm.Parameters.Add("@propertyName", SqlDbType.NVarChar).Value = propertyName; 

if (startTime.HasValue) 
{ 
    var startString = startTime.Value.ToUniversalTime().ToString("O"); 

    if (endTime.HasValue) 
    { 
     var endString = endTime.Value.ToUniversalTime().ToString("O"); 

     comm.CommandText += "Between"; 
     comm.Parameters.Add("@startTime", SqlDbType.DateTime2).Value = startString; 
     comm.Parameters.Add("@endTime", SqlDbType.DateTime2).Value = endString; 
    } 
    else 
    { 
     comm.CommandText += "After"; 
     comm.Parameters.Add("@dateTime", SqlDbType.DateTime2).Value = startString; 
    } 
} 

SqlDataReader reader = comm.ExecuteReader(); 

while (reader.Read()) 
{ 
    // ... 
} 

SQL Server存儲過程:

declare @str varchar(max) = 'select * from [dbo].[' + @tableName + '] where StartTime BETWEEN ''' + 
            CAST(@startTime as nvarchar(max)) + ''' AND ''' + CAST(@endTime as nvarchar(max)) + ''' order by StartTime asc' 
exec(@str) 

執行的示例性查詢:

USE [Construct3] 
GO 

DECLARE @return_value int 

EXEC @return_value = [dbo].[GetAllPropertyValuesBetween] 
     @datatypeName = N'HeadPose', 
     @propertyName = N'HeadRotationRadiansZ', 
     @startTime = '2014-12-31T19:00:00.0000000Z', 
     @endTime = '2014-12-31T20:00:00.0000000Z' 

SELECT 'Return Value' = @return_value 
GO 
+0

您是否試過閱讀此文? http://stackoverflow.com/questions/1314505/why-some-stored-procedures-do-not-return-data-in-asp-net-c-sharp – Nothing

+0

你運行SQL跟蹤來查看實際對服務器執行的語句? – AgustinCoder

回答

1

在存儲過程假設你的@startTime@endTime參數的類型DATETIME那麼你從日期時間做了雙轉換爲字符串,首先你這樣做對你的C#代碼:

var startString = startTime.Value.ToUniversalTime().ToString("O"); //This will create the datetime as a string using .NET format

你將它傳遞給存儲過程作爲DateTime2

comm.Parameters.Add("@startTime", SqlDbType.DateTime2).Value = startString;

和TH帶你將其轉換回字符串格式的SQL:

CAST(@startTime as nvarchar(max))

這可能是問題,當你從DATETIME做轉換到.NET和SQL字符串,不要指望他們有相同的結果,所以當你在數據庫上執行存儲過程時,你會得到結果,但是當你從.NET調用它時,由於日期錯誤,沒有結果。我建議的做法是將這些日期參數的值作爲正常的.NET DateTime值傳遞給存儲過程並將其轉換爲varchar。您可以使用SQL中的CONVERT函數來實現該功能,請參閱this link以獲取有關CONVERT日期格式的更多信息。

希望這會有所幫助。

+0

它看起來像這樣做了!我很驚訝地發現這是個問題,但是我拿@ AgustinCoder的建議來使用跟蹤器,發現日期輸入實際上是不正確的。 –

1

更改CommandText財產清除Parameters集合。完成文本後設置所有參數。

此外,你有什麼將容易受到SQL注入攻擊。您應該使用sp_executesql而不是exec(),以便安全地處理您的時間參數。我會給你一個懷疑的好處,即@tableName參數不是用戶可以輸入任意文本的東西,而是必須從服務器驗證的表格列表中進行選擇。