【问题标题】:passing multiple parameters to sql procedure as a single string variable将多个参数作为单个字符串变量传递给 sql 过程
【发布时间】:2011-01-10 06:40:27
【问题描述】:

从前端(studio 2008)我将值传递给 sql 过程:

字符串 a = “你好” + “098765” + “世界” + “90.0909”

这些是我连接成字符串 a 的 4 个不同的值;

现在我使用 c# sqlCommand 对象将此 string a 传递给 sql 过程。

现在,我如何在 sql 过程中检索这 4 个值,因为我已将过程创建为:

create procedure Proc_name (@concatenated_string varchar(100))
as
insert into table1 values(**how can i get those 4 values here**).

我使用了数组,但它不起作用。

【问题讨论】:

  • 为什么不在程序上只设置四个参数?
  • 听起来您正在尝试创建一个通用的“插入”过程来处理各种不同表的所有插入。如果是这样 - 为什么?!?!?您在代码质量(速度、可读性)方面一无所获,造成严重的安全问题,并且通常让每个人的生活都变得困难。
  • 您的字符串中没有分隔符,它以 hello098765world90.0909 结尾,这是没有意义的。至少如果你放一个 |, ¬ 或 , 或任何介于两者之间的东西,那么你就有机会拆分它......
  • ok ck 如果我将逗号作为分隔符,那么如何处理数组(尽管人们说不要使用通用过程,但我仍然想知道如何处理数组)?????? ?????

标签: c# sql-server-2005 procedures


【解决方案1】:
 public List<T> updateSiteDetails<T>(int SiteId, int CategoryId, string[] values)
    {
        int temp = values.Count();
        int Counter = 0;
        List<T> SiteDetails = null;
        var parameterData = new string[temp];
        var para = new string[temp];
        foreach (string value in values)
        {
            Counter =Counter++;
            parameterData[Counter] = "@,value"+Counter;
            para[Counter] = string.Format(","+value);
        }
        //string ParameterDatas=string.Join(",",parameterData);
        string parameterValue = string.Join(",",para);
        using (SBDEntities db = new SBDEntities())
        {
            SiteDetails = db.Database.SqlQuery<T>("Sp_Update_Data @SiteId,@CategoryId" + string.Join(",", parameterData),string.Join(",",para)
                   //new Object[] { new SqlParameter("@SiteId", SiteId),
                  // new SqlParameter("@CategoryId",CategoryId)}
        ).ToList();
            }
            return SiteDetails;
        }     

如果您在实体框架中使用存储过程

【讨论】:

    【解决方案2】:

    使用多个参数而不是 1,例如:

    CREATE PROCEDURE [dbo].[addUser]
    
        @idRole int,  
        @userName varchar(255),  
        @password varchar(255)
        AS
        BEGIN
        set nocount on
    
        insert into userTbl (  idRole , userName , password  )
         VALUES (  @idRole , @userName , @password  )
    
        return scope_identity();
        END
    
        GO
    

    【讨论】:

      【解决方案3】:

      如果您真的只想使用一个参数,那么可以考虑使用 XML 参数而不是字符串。

      【讨论】:

        【解决方案4】:

        如果您使用的是 SQL Server 2005,那么您可能希望将数据作为 XML 参数发送到您的存储过程。 This link完美解释流程

        下面是使用 .NET 3.5 和 C# 的代码示例部分

        // 示例对象

        [Serializable]
        internal class MyClass
        {
            internal string Property1 { get; set; }
            internal string Property2 { get; set; }
            internal int Property3 { get; set; }
            internal string Property4 { get; set; }
        }
        

        // 样本序列化

        internal static string SerializeObject<T>(T objectGraph)   
        {   
            StringBuilder sb = new StringBuilder();   
        
            XmlWriterSettings writerSettings = new XmlWriterSettings();   
            writerSettings.OmitXmlDeclaration = true;   
            writerSettings.Indent = true;   
        
            using (XmlWriter xmlWriter = XmlWriter.Create(sb, writerSettings))   
            {   
                XmlSerializer xs = new XmlSerializer(typeof(T));   
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();   
                ns.Add(String.Empty, String.Empty);   
                xs.Serialize(xmlWriter, objectGraph, ns);   
            }   
        
            return sb.ToString();   
        }  
        

        // 示例存储过程

        Create PROCEDURE [dbo].[MyProc]   
            @myClassXML XML   
        AS   
        BEGIN   
            INSERT INTO [dbo].[MyTable] 
            (   
                P1,   
                P2,   
                P3,   
                P4   
            )    
            SELECT    
                Container.ContainerCol.value('Property1[1]', 'varchar(50)') AS P1,   
                Container.ContainerCol.value('Property2[1]', 'varchar(50)') AS P2,     
                Container.ContainerCol.value('Property3[1]', 'int') AS P3,     
                Container.ContainerCol.value('Property4[1]', 'varchar(50)') AS P4,     
            FROM @myClassXML.nodes('//MyClass') AS Container(ContainerCol)    
        END
        

        我假设您已经阅读了此处其他答案的建议,并且没有创建通用的“插入任何内容”存储过程,因为这是您可以做的最糟糕的事情之一。

        注意:此代码是用 Notepad++ 编写的,因此未经测试。

        【讨论】:

          【解决方案5】:

          您可以用逗号连接这 4 个字符串,然后将其拆分回数据库中。

          例如

          declare @values as nvarchar(1000)
          set @values = 'hello,098765,world,90.0909'
          SELECT * FROM split(@values) 
          
          ----------------  SPLIT FUNCTION  --------------
          CREATE FUNCTION [dbo].[split]
          (
              @csv nvarchar(max)
          )
          RETURNS 
          @entries TABLE 
          (
              entry nvarchar(100)
          )
          AS
          BEGIN
              DECLARE @commaindex int
              SELECT @commaindex = CHARINDEX(',', @csv)
          
              IF @commaindex > 0 
              BEGIN
                  INSERT INTO @entries
                  -- insert left side
                  SELECT LTrim(RTrim(LEFT(@csv, @commaindex-1)))
                  -- pass right side recursively
                  UNION ALL
                  SELECT entry
                  FROM dbo.split(RIGHT(@csv, LEN(@csv) - @commaindex))        
              END
              ELSE
                  INSERT INTO @entries
                  SELECT LTrim(RTrim(@csv))
          
              RETURN
          END
          

          【讨论】:

            【解决方案6】:

            如果您想将数组传递到 SQL Server 以处理一个表上的“多行”更新,请阅读此famous article(s).

            如果你想要一个通用的存储过程来更新任何表,那么不要像其他 cmets 那样

            【讨论】:

              【解决方案7】:

              执行此操作的标准方法是在过程中使用四个参数:

              create procedure Proc_name (@param1 varchar(100), 
                  @param2 varchar(100), 
                  @param3 varchar(100), 
                  @param4 varchar(100)) 
              as 
              insert into table1 values(@param1, @param2, @param3, @param4)
              

              然后从您的代码中(给出一个使用 ADO.NET 的 c# 示例)

              using (SqlConnection connection = new SqlConnection(connectionString))
              {
                  // Create the command and set its properties.
                  SqlCommand command = new SqlCommand();
                  SqlCommand command = new SqlCommand 
                     ("Proc_name", connection); 
              
                  command.CommandType = CommandType.StoredProcedure;
              
                  // Add the input parameters and set the properties.
                  SqlParameter parameter1 = new SqlParameter();
                  parameter.ParameterName = "@Param1";
                  parameter.SqlDbType = SqlDbType.NVarChar;
                  parameter.Direction = ParameterDirection.Input;
                  parameter.Value = param1;
              
                  SqlParameter parameter2 = new SqlParameter();
                  parameter.ParameterName = "@Param2";
                  parameter.SqlDbType = SqlDbType.NVarChar;
                  parameter.Direction = ParameterDirection.Input;
                  parameter.Value = param2;
              
                  // Same for params 3 and 4...
              
              
                  // Add the parameter to the Parameters collection. 
                  command.Parameters.Add(parameter1);
                  command.Parameters.Add(parameter2);
                  command.Parameters.Add(parameter3);
                  command.Parameters.Add(parameter4);
              
              
                  // Open the connection and execute the reader.
                  connection.Open();
                  SqlDataReader reader = command.ExecuteNonQuery();
              
                  reader.Close();
              }
              

              【讨论】:

              • 有了 EnterpriseLibrary,这变得更加更干净了。
              猜你喜欢
              • 2019-06-10
              • 2016-07-21
              • 1970-01-01
              • 2011-03-29
              • 1970-01-01
              • 2016-08-10
              • 1970-01-01
              • 2020-08-19
              • 2023-04-02
              相关资源
              最近更新 更多