将多个参数作为单个字符串变量传递给sql过程

时间:2010-01-28 05:00:02

标签: c# sql-server-2005 procedures

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

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

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

现在我使用c#sqlCommand对象将字符串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**).

我使用了数组,但它没有用。

7 个答案:

答案 0 :(得分:6)

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

如果您希望通用存储过程更新任何表,那么请不要按照其他注释

答案 1 :(得分:5)

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

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();
}

答案 2 :(得分: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

我假设你已经阅读了其他答案的建议,而不是创建一个通用的“Insert Anything”存储过程,因为这是你可以做的最糟糕的事情之一。

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

答案 3 :(得分:1)

使用多个参数而不是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

答案 4 :(得分:1)

你可以用逗号连接4个字符串,并在数据库中将其拆分回来。

E.g。

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

 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;
        }     

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