C# 如果记录存在,则返回ID,否则插入并返回ID

C# 如果记录存在,则返回ID,否则插入并返回ID,c#,sql-server,visual-studio-2013,C#,Sql Server,Visual Studio 2013,我有下面的C#代码来检查记录是否不存在,插入并返回id。但我还需要如果记录存在,它返回值。为了实现这一点,我应该对C#和SQL部分做什么更改?数据库是sQL server。我还必须为此使用ExecuteScalar()吗 con.Open(); // Insert ClinRefFileTypeMaster string command1 = string.Format( "if NOT exists (select * from [ClinRefFileTypeMaster] whe

我有下面的C#代码来检查记录是否不存在,插入并返回id。但我还需要如果记录存在,它返回值。为了实现这一点,我应该对C#和SQL部分做什么更改?数据库是sQL server。我还必须为此使用ExecuteScalar()吗

con.Open();

// Insert ClinRefFileTypeMaster
string command1 = string.Format(
    "if NOT exists (select * from [ClinRefFileTypeMaster] where [ClinRefTypeName] = '{0}') Insert into [ClinRefFileTypeMaster] ([ClinRefTypeName]) output INSERTED.[ClinRefTypeID] VALUES('{0}')",
      dataToParse[i][0]
      );
SqlCommand ClinRefFileTypeMaster = new SqlCommand(command1, con);

// check if there is an value 
object checkValue = ClinRefFileTypeMaster.ExecuteScalar(); 

if (checkValue != null)
    ClinRefFileTypeId = (int)checkValue;

您还需要将IF EXISTS子句添加到SQL语句中,检查相同的条件,并提供返回值的逻辑

如果需要ExecuteReader从数据库返回值,那么使用ExecuteReader会更好

二( 我个人会将逻辑分成两个查询,并在c#中运行If语句,检查值是否在数据库中,然后更新数据库,或者从数据库返回值

conn.open()
int CheckDb;
String Command1 = "select * from [ClinRefFileTypeMaster] where [ClinRefTypeName] = @ClinRefFileTypeId";
using (SqlCommand ClinRefFileTypeMaster = new SqlCommand(command1, con);
    {
         cmd.Parameters.AddWithValue("@ClinRefFileTypeId", {0});
         CheckDb = (int)ClinRefFileTypeMaster.ExecuteScalar();
     }
If (CheckDb != 0)
    //Logic for returning the value from the database
Else
    //Here you can request user check data or insert the value into the database.

您还需要将IF EXISTS子句添加到SQL语句中,检查相同的条件,并提供返回值的逻辑

如果需要ExecuteReader从数据库返回值,那么使用ExecuteReader会更好

二( 我个人会将逻辑分成两个查询,并在c#中运行If语句,检查值是否在数据库中,然后更新数据库,或者从数据库返回值

conn.open()
int CheckDb;
String Command1 = "select * from [ClinRefFileTypeMaster] where [ClinRefTypeName] = @ClinRefFileTypeId";
using (SqlCommand ClinRefFileTypeMaster = new SqlCommand(command1, con);
    {
         cmd.Parameters.AddWithValue("@ClinRefFileTypeId", {0});
         CheckDb = (int)ClinRefFileTypeMaster.ExecuteScalar();
     }
If (CheckDb != 0)
    //Logic for returning the value from the database
Else
    //Here you can request user check data or insert the value into the database.

为您执行所有操作的存储过程看起来像

CREATE PROCEDURE usp_Get_ClinRefTypeID
  @ClinRefTypeName  VARCHAR(100),
  @ClinRefTypeID    INT OUTPUT
AS
BEGIN
  SET NOCOUNT ON;

    DECLARE @NewID TABLE(ClinRefTypeID INT);

  SELECT @ClinRefTypeID = [ClinRefTypeID]
  FROM [ClinRefFileTypeMaster] 
  where [ClinRefTypeName] = @ClinRefTypeName;

  IF (@ClinRefTypeID IS NULL)
    BEGIN
        INSERT INTO [ClinRefFileTypeMaster] ([ClinRefTypeName]) 
        OUTPUT inserted.[ClinRefTypeID]  INTO @NewID(ClinRefTypeID)
        VALUES(@ClinRefTypeName)

        SELECT @ClinRefTypeID = [ClinRefTypeID] FROM @NewID
    END

END
con.Open();

// Insert ClinRefFileTypeMaster
    SqlCommand cmd = new SqlCommand("usp_Get_ClinRefTypeID", con);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@ClinRefTypeID", SqlDbType.Int).Direction = ParameterDirection.Output;
    cmd.Parameters.Add(new SqlParameter("@ClinRefTypeName", dataToParse));

// get the value back from the output parameter 
    cmd.ExecuteNonQuery();
    int ClinRefTypeName = Convert.ToInt32(cmd.Parameters["@ClinRefTypeID"].Value);
你的C代码看起来像

CREATE PROCEDURE usp_Get_ClinRefTypeID
  @ClinRefTypeName  VARCHAR(100),
  @ClinRefTypeID    INT OUTPUT
AS
BEGIN
  SET NOCOUNT ON;

    DECLARE @NewID TABLE(ClinRefTypeID INT);

  SELECT @ClinRefTypeID = [ClinRefTypeID]
  FROM [ClinRefFileTypeMaster] 
  where [ClinRefTypeName] = @ClinRefTypeName;

  IF (@ClinRefTypeID IS NULL)
    BEGIN
        INSERT INTO [ClinRefFileTypeMaster] ([ClinRefTypeName]) 
        OUTPUT inserted.[ClinRefTypeID]  INTO @NewID(ClinRefTypeID)
        VALUES(@ClinRefTypeName)

        SELECT @ClinRefTypeID = [ClinRefTypeID] FROM @NewID
    END

END
con.Open();

// Insert ClinRefFileTypeMaster
    SqlCommand cmd = new SqlCommand("usp_Get_ClinRefTypeID", con);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@ClinRefTypeID", SqlDbType.Int).Direction = ParameterDirection.Output;
    cmd.Parameters.Add(new SqlParameter("@ClinRefTypeName", dataToParse));

// get the value back from the output parameter 
    cmd.ExecuteNonQuery();
    int ClinRefTypeName = Convert.ToInt32(cmd.Parameters["@ClinRefTypeID"].Value);

为您执行所有操作的存储过程看起来像

CREATE PROCEDURE usp_Get_ClinRefTypeID
  @ClinRefTypeName  VARCHAR(100),
  @ClinRefTypeID    INT OUTPUT
AS
BEGIN
  SET NOCOUNT ON;

    DECLARE @NewID TABLE(ClinRefTypeID INT);

  SELECT @ClinRefTypeID = [ClinRefTypeID]
  FROM [ClinRefFileTypeMaster] 
  where [ClinRefTypeName] = @ClinRefTypeName;

  IF (@ClinRefTypeID IS NULL)
    BEGIN
        INSERT INTO [ClinRefFileTypeMaster] ([ClinRefTypeName]) 
        OUTPUT inserted.[ClinRefTypeID]  INTO @NewID(ClinRefTypeID)
        VALUES(@ClinRefTypeName)

        SELECT @ClinRefTypeID = [ClinRefTypeID] FROM @NewID
    END

END
con.Open();

// Insert ClinRefFileTypeMaster
    SqlCommand cmd = new SqlCommand("usp_Get_ClinRefTypeID", con);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@ClinRefTypeID", SqlDbType.Int).Direction = ParameterDirection.Output;
    cmd.Parameters.Add(new SqlParameter("@ClinRefTypeName", dataToParse));

// get the value back from the output parameter 
    cmd.ExecuteNonQuery();
    int ClinRefTypeName = Convert.ToInt32(cmd.Parameters["@ClinRefTypeID"].Value);
你的C代码看起来像

CREATE PROCEDURE usp_Get_ClinRefTypeID
  @ClinRefTypeName  VARCHAR(100),
  @ClinRefTypeID    INT OUTPUT
AS
BEGIN
  SET NOCOUNT ON;

    DECLARE @NewID TABLE(ClinRefTypeID INT);

  SELECT @ClinRefTypeID = [ClinRefTypeID]
  FROM [ClinRefFileTypeMaster] 
  where [ClinRefTypeName] = @ClinRefTypeName;

  IF (@ClinRefTypeID IS NULL)
    BEGIN
        INSERT INTO [ClinRefFileTypeMaster] ([ClinRefTypeName]) 
        OUTPUT inserted.[ClinRefTypeID]  INTO @NewID(ClinRefTypeID)
        VALUES(@ClinRefTypeName)

        SELECT @ClinRefTypeID = [ClinRefTypeID] FROM @NewID
    END

END
con.Open();

// Insert ClinRefFileTypeMaster
    SqlCommand cmd = new SqlCommand("usp_Get_ClinRefTypeID", con);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@ClinRefTypeID", SqlDbType.Int).Direction = ParameterDirection.Output;
    cmd.Parameters.Add(new SqlParameter("@ClinRefTypeName", dataToParse));

// get the value back from the output parameter 
    cmd.ExecuteNonQuery();
    int ClinRefTypeName = Convert.ToInt32(cmd.Parameters["@ClinRefTypeID"].Value);

在数据库(即存储过程)中执行所有这些操作

if not exists (select 1 from  [ClinRefFileTypeMaster] where [ClinRefTypeName] =@name)
begin
Insert into [ClinRefFileTypeMaster] ([ClinRefTypeName]) values (@name) 
end
else
begin
select (as desired) from ClinRefFileTypeMaster where where [ClinRefTypeName] =@name
end

这将插入新记录或选择已插入的信息

在数据库中执行所有操作,即存储过程

if not exists (select 1 from  [ClinRefFileTypeMaster] where [ClinRefTypeName] =@name)
begin
Insert into [ClinRefFileTypeMaster] ([ClinRefTypeName]) values (@name) 
end
else
begin
select (as desired) from ClinRefFileTypeMaster where where [ClinRefTypeName] =@name
end

这将插入新记录或选择已插入的信息

实现这一点的方法有很多。1) 您可以在内联Sql中完成所有操作2)您可以在存储过程中完成所有操作。3) 您可以在代码中完成这一切,但需要拆分代码,因为坦率地说,这段代码做的太多了。一般来说,我会避免使用相同的方法插入/查询

还可以尝试使用SqlParameters,而不是将查询构建为字符串concat

我建议这样做,使代码更具可读性

    public int InsertAndRetrieveClientRefId(string clientRefTypeName)
    {
        int id = GetIdIfRecordExists(clientRefTypeName);

        if (id == 0)
        { 
            // insert logic here

            id = GetIdIfRecordExists(clientRefTypeName);
        }

        return id;
    }

    public int GetIdIfRecordExists(string clientRefTypeName)
    {
        int id = 0;

        string command = "select id from ClinRefFileTypeMaster where ClinRefTypeName = @ClinRefTypeName";
        SqlParameter nameParameter = new SqlParameter("@ClinRefTypeName", System.Data.SqlDbType.NVarChar, 10) { Value = clientRefTypeName };

        using (SqlConnection connection = new SqlConnection("ConnectionString"))
        {
            using (SqlCommand cmd = new SqlCommand(command))
            {
                cmd.Parameters.Add(newParameter);
                connection.Open();
                cmd.Connection = connection;
                int.TryParse(cmd.ExecuteScalar().ToString(), out id);
            }
        }

        return id;
    }

实现这一点的方法有很多。1) 您可以在内联Sql中完成所有操作2)您可以在存储过程中完成所有操作。3) 您可以在代码中完成这一切,但需要拆分代码,因为坦率地说,这段代码做的太多了。一般来说,我会避免使用相同的方法插入/查询

还可以尝试使用SqlParameters,而不是将查询构建为字符串concat

我建议这样做,使代码更具可读性

    public int InsertAndRetrieveClientRefId(string clientRefTypeName)
    {
        int id = GetIdIfRecordExists(clientRefTypeName);

        if (id == 0)
        { 
            // insert logic here

            id = GetIdIfRecordExists(clientRefTypeName);
        }

        return id;
    }

    public int GetIdIfRecordExists(string clientRefTypeName)
    {
        int id = 0;

        string command = "select id from ClinRefFileTypeMaster where ClinRefTypeName = @ClinRefTypeName";
        SqlParameter nameParameter = new SqlParameter("@ClinRefTypeName", System.Data.SqlDbType.NVarChar, 10) { Value = clientRefTypeName };

        using (SqlConnection connection = new SqlConnection("ConnectionString"))
        {
            using (SqlCommand cmd = new SqlCommand(command))
            {
                cmd.Parameters.Add(newParameter);
                connection.Open();
                cmd.Connection = connection;
                int.TryParse(cmd.ExecuteScalar().ToString(), out id);
            }
        }

        return id;
    }

如果要执行insert操作,我认为最好调用存储过程并在该过程中编写查询。这样会更安全

SqlCommand command = new SqlCommand("procedureName",con);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue(“@value1”, txtValue1.Text);
command.Parameters.AddWithValue(“@value2”, Value2);
int value = command.ExecuteScalar();

如果要传递查询字符串,可以调用select query,如果返回
null
则执行插入操作,并使用
scope\u Identity()
获取
ID

INSERT INTO YourTable(val1, val2, val3 ...) 
VALUES(@val1, @val2, @val3...);
SELECT SCOPE_IDENTITY();

如果要执行insert操作,我认为最好调用存储过程并在该过程中编写查询。这样会更安全

SqlCommand command = new SqlCommand("procedureName",con);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue(“@value1”, txtValue1.Text);
command.Parameters.AddWithValue(“@value2”, Value2);
int value = command.ExecuteScalar();

如果要传递查询字符串,可以调用select query,如果返回
null
则执行插入操作,并使用
scope\u Identity()
获取
ID

INSERT INTO YourTable(val1, val2, val3 ...) 
VALUES(@val1, @val2, @val3...);
SELECT SCOPE_IDENTITY();

您可能需要MERGE语句,也可能需要拆分语句。仅在if块中插入。选择外部。SQL非常适合缓存,如果您刚刚插入了一些东西,那么选择它可能会非常快。此外,该查询很难读取,请以@开头将其转换为多行字符串。这看起来不清楚。类似的解决方案是或使用DECLARE recordId int;然后从tbl中选择recordId=idColumn…可能需要MERGE语句可能需要拆分语句。仅在if块中插入。选择外部。SQL非常适合缓存,如果您刚刚插入了一些东西,那么选择它可能会非常快。此外,该查询很难读取,请以@开头将其转换为多行字符串。这看起来不清楚。类似的解决方案是或使用DECLARE recordId int;然后从tbl中选择recordId=idColumn…是的,我强烈建议这样做!更安全,更容易维护。是的,我强烈建议这样做!更安全,更容易维护。谢谢,这对我来说很有效,因为使用存储过程不是我的选择。我想你只是忘了在命令中添加nameParameter!我这样做了,效果很好。很高兴成功了。我已经更新了答案,将参数添加到命令中。谢谢,这对我来说很有效,因为使用存储过程对我来说不是一个选项。我想你只是忘了在命令中添加nameParameter!我这样做了,效果很好。很高兴成功了。我已经更新了答案,将参数添加到命令中。