c# - 执行SQL脚本以传输数据

时间:2017-11-01 03:28:13

标签: c# sql-server ssms

我正在使用c#中的程序,我有一个布局,如下图所示:

该程序的目的是在SQL Server中执行数据存档。如果我选择"创建表",它将在我的数据库中生成新表(应该按顺序生成大约40个表),它们具有与原始表相似的表结构(列,约束,触发器等)数据库也是如此。这是如何工作的我将在c#中执行SQL脚本并调用它们(所有40个脚本)来创建表。

现在,我添加了另一个按钮"传输数据"它将在旧数据中选择特定数据(基于日期)并将它们传输到我创建的新表中。我将使用查询Insert Into .... SELECT from来传输数据。

我的问题是我应该创建用于传输数据的sql脚本并在c#中执行它们,还是只将SQL查询放在我的c#代码中?

如果我使用SQL脚本,我是否应该将它们分成40个脚本或将所有查询放在1个脚本中?我知道如果我将所有内容都放在一个脚本中就好像发生了错误一样,这很麻烦。很难找到问题的根源。

以下是sql查询的示例:

SET IDENTITY_INSERT Kiosk_Log_New ON
INSERT INTO Kiosk_Log_New(LOGID,
                          logAPPID,
                          logLOGTID,
                          logGUID,
                          logOriginator,
                          logReference,
                          logAssemblyName,
                          logFunctionName,
                          logMessage,
                          logException,
                          CreatedBy,
                          CreatedDate)
SELECT                  LOGID,
                          logAPPID,
                          logLOGTID,
                          logGUID,
                          logOriginator,
                          logReference,
                          logAssemblyName,
                          logFunctionName,
                          logMessage,
                          logException,
                          CreatedBy,
                          CreatedDate FROM Kiosk_Log
WHERE CreatedDate BETWEEN '2015-01-01' AND GETDATE()

编辑:由于许多建议的存储过程是最佳选择,这将是我的创建表脚本:

string constr = ConfigurationManager.ConnectionStrings [" constr"]。ConnectionString;         / *打开sql连接来执行SQL脚本:PromotionEvent_New * /         尝试         {             使用(SqlConnection con = new SqlConnection(constr))             {                 con.Open();                 FileInfo file = new FileInfo(" C:\ Users \ 88106221 \ Documents \ SQL Server Management Studio \ PromotionEvent_New.sql");                 string script = file.OpenText()。ReadToEnd();                 Server server = new Server(new ServerConnection(con));                 server.ConnectionContext.ExecuteNonQuery(脚本);                 显示(" PromotionEvent_New表已成功创建");                 con.Close();

        }

    }
    catch(Exception ex)
    {

        textBox1.AppendText(string.Format("{0}", Environment.NewLine));
        textBox1.AppendText(string.Format("{0} MainPage_Load() exception - {1}{2}", _strThisAppName, ex.Message, Environment.NewLine));
        Display(ex.Message + "PromotionEvent_New could not be created");
        textBox1.AppendText(string.Format("{0}", Environment.NewLine));
        Debug.WriteLine(string.Format("{0} MainPage_Load() exception - {1}", _strThisAppName, ex.Message));


    }

2 个答案:

答案 0 :(得分:1)

根据表的命名和设计,我建议创建一个脚本来为此创建一个存储过程,为每个表生成一个。我不是脚本专家,但是对于为每个表或至少在脚本中定义的表生成审计跟踪的脚本都是一样的。

在c#应用程序中对此进行硬编码是一个很大的问题,因为数据库可能会发生变化。我们希望我们的应用程序能够以最少的努力灵活地进行更改。

如果生成脚本来创建存储过程对您来说很难,我仍然建议您为此任务手动创建存储过程。

答案 1 :(得分:1)

最好将存储过程与事务一起使用来执行所有INSERT查询。

由于多种原因,不建议按照John Ephraim Tugado的上一篇文章中的说明提交C#代码中的查询;最重要的原因是,

  • 更容易维护INSERT查询
  • Web服务器和数据库服务器之间的最小带宽消耗

从C#代码发送长查询字符串将在Web服务器和数据库服务器之间消耗更多带宽,并且可能会在高流量情况下降低数据库响应速度。

您可以对数据库执行以下T-SQL代码,以便为transferring/archiving data创建存档表的存储过程。此过程可确保您在事务中执行所有INSERTS,从而确保您不会遇到孤立表和不必要的麻烦。

传输数据的存储过程

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Lord Cookie
-- Create date: 11/01/2017
-- Description: Transfers data to existing archived tables
-- =============================================
CREATE PROCEDURE dbo.ArchiveData

AS
BEGIN

    SET NOCOUNT ON;
    BEGIN TRY
         --use transaction when inserting data else you may end up with orphaned data and hard to debug issues later on
        BEGIN TRANSACTION

        --add your INSERT queries one after the other below
        SET IDENTITY_INSERT Kiosk_Log_New ON
        INSERT INTO Kiosk_Log_New (LOGID,
        logAPPID,
        logLOGTID,
        logGUID,
        logOriginator,
        logReference,
        logAssemblyName,
        logFunctionName,
        logMessage,
        logException,
        CreatedBy,
        CreatedDate)
                SELECT
                    LOGID
                    ,logAPPID
                    ,logLOGTID
                    ,logGUID
                    ,logOriginator
                    ,logReference
                    ,logAssemblyName
                    ,logFunctionName
                    ,logMessage
                    ,logException
                    ,CreatedBy
                    ,CreatedDate
                FROM Kiosk_Log
                WHERE CreatedDate BETWEEN '2015-01-01' AND GETDATE()

        --add more of your insert queries below


        -- finally commit transaction
        COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        DECLARE @errorDetails NVARCHAR(MAX);
        set @errorDetails = 'Error ' + CONVERT(VARCHAR(50), ERROR_NUMBER()) +
        ', Severity ' + CONVERT(VARCHAR(5), ERROR_SEVERITY()) +
        ', State ' + CONVERT(VARCHAR(5), ERROR_STATE()) +
        ', Line ' + CONVERT(VARCHAR(5), ERROR_LINE());

          --roll back the transaction
        IF XACT_STATE() <> 0
        BEGIN
            ROLLBACK TRANSACTION
        END

        --you can log the above error message and/or re-throw the error so your C# code will see an error
        --but do this only after rolling back
    END CATCH;
END
GO

然后,您可以使用C#调用上述存储过程,如下面的示例代码所示。

使用C#

调用上述存储过程
using(SqlConnection sqlConn = new SqlConnection("Your database Connection String")) {
 using(SqlCommand cmd = new SqlCommand()) {
  cmd.CommandText = "dbo.ArchiveData";
  cmd.CommandType = CommandType.StoredProcedure;
  cmd.Connection = sqlConn;
  sqlConn.Open();
  cmd.ExecuteNonQuery();
 }
}