我可以在一个查询中创建不同表中的行吗?

时间:2017-10-26 13:25:42

标签: c# sql

我尝试同时创建多个行,每行实现前一行主键。有没有办法可以在一个查询中实现所有这些,而不是创建多个查询来执行此操作,如代码示例所示?

public void CreateMessage(int profileId, String text, int chatId)
    {
        string stmt = "INSERT INTO Activity (profileID, timeStamp) OUTPUT INSERTED.activityID values (" + profileId + ", '" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "')";
        SqlDataReader reader = new SqlCommand(stmt, con).ExecuteReader();
        reader.Read();

        stmt = "INSERT INTO Text(activityID, message) OUTPUT INSERTED.textID values(" + Int32.Parse(reader["activityID"].ToString()) + ", (select cast('" + text + "' as varbinary(max))))";
        reader.Close();
        reader = new SqlCommand(stmt, con).ExecuteReader();
        reader.Read();

        stmt = "INSERT INTO Message (textID, chatID) values (" + Int32.Parse(reader["textID"].ToString()) + ", " + chatId + ")";
        reader.Close();
        new SqlCommand(stmt, con).ExecuteNonQuery();
    }

4 个答案:

答案 0 :(得分:0)

SqlDataReader用于以一种有效的方式读取数据。您可以从select或存储过程调用中检索数据,并一次读取一条记录。

如果要执行一个命令块,可以在代码中使用事务,检查SQlConnection.BeginTransaction,或使用存储过程(内部应该使用事务)将该任务委派给数据库。

答案 1 :(得分:0)

通常你可以在语句之间加一个分号,并将多个命令作为一个字符串发送。但是,您将在下一个语句中使用一个语句的结果。这意味着您必须一次运行一个语句并在执行下一个语句之前读取结果。

您可以在c#或SQL存储过程中执行此操作。在任何一种情况下,您都可以使用transactions来确保一次写入所有内容。

答案 2 :(得分:0)

您可能唯一需要做的就是在不同的;行之间输入insert,请参阅下面的示例:

public void CreateMessage(int profileId, String text, int chatId)
    {
        string stmt = "INSERT INTO Activity (profileID, timeStamp) OUTPUT INSERTED.activityID values (" + profileId + ", '" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "')";
        SqlDataReader reader = new SqlCommand(stmt, con).ExecuteReader();
        reader.Read();

        stmt = "INSERT INTO Text(activityID, message) OUTPUT INSERTED.textID values(" + Int32.Parse(reader["activityID"].ToString()) + ", (select cast('" + text + "' as varbinary(max))))";
        reader.Close();
        reader = new SqlCommand(stmt, con).ExecuteReader();
        reader.Read();

        stmt = "INSERT INTO Message (textID, chatID) values (" + Int32.Parse(reader["textID"].ToString()) + ", " + chatId + ")";
        reader.Close();
        new SqlCommand(stmt, con).ExecuteNonQuery();
    }

将成为

    public void CreateMessage(int profileId, String text, int chatId)
        {
            string stmt = "INSERT INTO Activity (profileID, timeStamp) OUTPUT INSERTED.activityID values (" + profileId + ", '" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "');
INSERT INTO Message (textID, chatID) values (" + Int32.Parse(reader["textID"].ToString()) + ", " + chatId + ");
INSERT INTO Text(activityID, message) OUTPUT INSERTED.textID values(" + Int32.Parse(reader["activityID"].ToString()) + ", (select cast('" + text + "' as varbinary(max))))";
            SqlDataReader reader = new SqlCommand(stmt, con).ExecuteReader();
            reader.Read();
        }

我希望这能解决你的问题,如果我说错了!祝你好运

答案 3 :(得分:0)

最好将此代码包装在存储过程中,但没有它就可以。注意事务,有必要保持数据的完整性。

        public void CreateMessage(int profileId, String text, int chatId)
        {
            string stmt = string.Format(
@"DECLARE @profileId int;
DECLARE @text nvarchar(4000);
DECLARE @chatId int;
DECLARE @id int;

SELECT
    @profileId = {0},
    @chatId = {1},
    @text = N'",
                profileId.ToString(), chatId.ToString());

            stmt += text;
            stmt +=
@"';

BEGIN TRAN;

INSERT INTO Activity (profileID, timeStamp) VALUES(@profileId, getdate());
IF @@ERROR = 0
    SET @id = @@IDENTITY;
ELSE
    GOTO on_roll_back;

INSERT INTO Text (activityID, message) values(@id, (select cast(@text as varbinary(max))));
IF @@ERROR = 0
    SET @id = @@IDENTITY;
ELSE
    GOTO on_roll_back;

INSERT INTO Message (textID, chatID) values (@id, @chatId);
IF @@ERROR = 0 BEGIN
    COMMIT TRAN;
    GOTO on_finish; 
END;

on_roll_back:
ROLLBACK TRAN;

on_finish:";

            using (SqlCommand cmd = conn.CreateCommand())
            {
                cmd.CommandText = stmt;
                cmd.ExecuteNonQuery();
            }
        }