2012-09-12 70 views
0

可能重複:
SQL Server & .net support calling a stored procedure with param's values wihout providing param's names?C#SQL執行存儲procudere不管傳遞的參數名稱

我想打電話給一個Command.ExecuteReader卻()存儲過程型的,但我不希望我傳遞的參數名稱與SP中的相同。下面是什麼,我試圖做一個樣品

SP:

ALTER PROCEDURE SPName 
@Id nvarchar(50) 
AS 
BEGIN 
    SET NOCOUNT ON; 
SELECT * FROM TableName 
WHERE ColumnName = @Id 
END 
GO 

代碼:

using (SqlCommand command = new SqlCommand(spName, connection) { CommandType = CommandType.StoredProcedure }) 
{ 
    command.parameters.Add(new SqlParameter(*paramaeter name*, sqlDbType.nvarchar){ Value = "SomeValue"}; 
} 
+0

所以你不想傳遞參數或者你不知道參數名稱? –

+3

如果我理解正確,你想調用一個參數叫做@somethingelse的參數調用@Id說的sp。我不認爲這是可能的,但我也在努力理解你爲什麼想要 - 你想解決什麼問題? –

+0

我想寫一個通用的方法,其中我傳遞參數對象[],並通過它們循環填充參數集合傳遞給SP。我的觀點是我不想被迫通過param的名字。 – ancdev

回答

1

簡單的事實 - 你最終不得不調用存儲時,使用正確的參數名過程,因爲SQL服務器通過名稱綁定參數(即使您使用EXEC調用SP而不使用命名參數,解析器將按名稱從左到右進行綁定)。

所以如果你想使用不同的名字,你需要在你的SqlCommand和目標SP之間引入一箇中間層。

但如果你只是想不關心名字,並讓它自動發現 - 那麼你可以使用Conrad Frix提到的技術在他接受的答案上SQL Server & .net support calling a stored procedure with param's values wihout providing param's names? - 這就是爲什麼我已經標記爲重複,因爲它最終是你想做什麼,即使原因不同。

1

對於SqlServer,有一個DeriveParameters方法,它接受一個命令對象並向數據庫查詢請求的存儲過程的參數(名稱和類型)。

然後,您可以遍歷它們並提供值。

注意:這意味着額外的旅行到數據庫,所以如果你經常需要這個,你可能想緩存結果。

0

下面的方法可以讓你編寫通用的代碼調用存儲過程,也使您能夠爲每個不同的存儲過程

public delegate void SqlCOmmandDelegate(SqlCommand command); 

public class Dal 
{ 
    public void ExecuteStoredProcedure(string procedureName, 
     SqlCommandDelgate commandDelegate) 
    { 
     using (SqlConnection connection = new SqlConnection()) 
     { 
      connection.ConnectionString = GetConnectionString(); 
      using (SqlCommand command = connection.CreateCommand()) 
      { 
       command.CommandType = CommandType.StoredProcedure; 
       command.CommandText = procedureName; 
       connection.Open(); 
       commandDelegate(command); 
      } 
     } 
    } 
} 

class UsesDal 
{ 
    public CallFirstProcedure(int value) 
    { 
     string userName; 

     ExecuteStoredProcedure("FIRST_PROCEDURE", 
      delegate(SqlCommand command) 
      { 
       command.Parameters.Add("UserID", value); 
       command.ExecuteReader(); 

       //Do stuff with results e.g. 
       username = command.Parameters.Parameters["UserName"].ToString(); 
      } 
    } 

    public CallOtherProcedure(string value) 
    { 
     int id; 
     ExecuteStoredProcedure("OTHER_PROCEDURE", 
      delegate(SqlCommand command) 
      { 
       command.Parameters.Add("ParameterName", value); 
       id = command.ExecuteScalar(); 
      } 
    } 
} 
2

執行特定的操作。如果你想有一個通用的樣式功能,而不需要靈活性一個額外的往返旅行,你很高興使用反射,你可以使用這樣的東西。

// Return an array of SqlParameter's by using reflection on ParamObject 
private static SqlParameter[] GetParametersFromObject(object ParamObject) 
{ 

    var Params = new List<SqlParameter>(); 

    foreach(var PropInfo in ParamObject.GetType().GetProperties()) 
    { 
     Params.Add(new SqlParameter(PropInfo.Name, PropInfo.GetValue(ParamObject, null))); 
    } 

    return Params.ToArray(); 

} 

public static void ExecuteSP(SqlConnection Connection, string SPName, object ParamObject) 
{ 

    using(var Command = new SqlCommand()) 
    { 

     Command.Connection = Connection; 
     Command.CommandType = CommandType.StoredProcedure; 
     Command.CommandText = SPName; 

     Command.Parameters.AddRange(GetParametersFromObject(ParamObject)); 

     // Command.ExecuteReader()... 

    } 

} 

這使用反射從匿名對象中獲取屬性名稱和值來填充SqlCommand。這可以這樣使用;

ExecuteSP(Conn, "GetStuff", new { Id = 7, Name = "Test" }); 

這種方式ExecuteSP是'通用',當你調用ExecuteSP時你選擇參數名和值。

相關問題