如何从C#中正确执行链接服务器存储过程

时间:2019-05-17 14:32:10

标签: c# sql-server

我想执行位于链接服务器数据库中的存储过程。目前,我正在SSMS中使用它:

library(shiny)
library(shinyjs)

library(dplyr)
library(DT)

options(DT.options = list(pageLength = 5))
df = as.data.frame(
        cbind(
                matrix(round(rnorm(50), 3), 10),
                sample(0:1, 10, TRUE),
                rep(FALSE, 10)
        )
)
# getwd()
setwd(here::here())
# write.csv(df, "data/df_test.csv")

ui <- fluidPage(
        h2("Last clicked:"),
        verbatimTextOutput("last_clicked"),
        actionButton("reset", "Reset clicked value"),
        h2("Datatable:"),
        DT::dataTableOutput("dt"),
        useShinyjs(),
        extendShinyjs(text = paste0("shinyjs.resetDTClick = function() { Shiny.onInputChange('dt_cell_clicked', null); }"))
)

server <- function(input, output) {

        # the last clicked value
        output$last_clicked <- renderPrint({
                str(input$dt_cell_clicked)
        })

        df_new <- reactive({

                # res <- read.csv("data/df_test.csv")
                res <- df
                res
        })

        output$dt <- DT::renderDataTable({
                # DT::datatable(head(mtcars, 2))
                DT::datatable(df_new(), select = "none", editable = TRUE) %>% formatStyle(
                        'V1', 'V6',
                        backgroundColor = styleEqual(c(0, 1), c('gray', 'yellow'))
                )
        })

        observeEvent(input$dt_cell_clicked, {
                validate(need(length(input$dt_cell_clicked) > 0, ''))
                # alert("You clicked something!")

                if(!is.null(input$dt_cell_clicked)){
                        # df[input$dt_cell_clicked$row, input$dt_cell_clicked$column] <- ifelse(0, 1, 0)
                        cat("changing value")
                        df_test <- df_new()
                        df_test[input$dt_cell_clicked$row, input$dt_cell_clicked$column] <- ifelse(0, 1, 0)
                        write.csv(df_test, "data/df_test.csv")
                        rm(df_test)
                        # i
                }
        })

        # use dt_cell_clicked to infer on bool cell

        # df_new <- eventReactive(input$dt_cell_clicked, {
        # df_new <- reactive({
        #
        # })

        observeEvent(input$reset, {
                js$resetDTClick()
        })
}

shinyApp(ui, server)

这会将来自INSERT INTO myTable EXEC [LINKEDSERVER\LINKED].[Data_Base_Name].[Store].usp_GetInfo 1, 1, NULL, 'H' 的存储过程的结果数据插入我的本地数据库中

我希望能够使用C#的命令来执行此操作,请问有正确的方法吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以从DataContext执行SP:

using (DataContext ctx = DataContext())
{
    int result = ctx.SP_ProcedureName("1", "2", "3");
}

但是首先,您必须在添加表时从数据库中将它添加到DataContext Diagram中,但要从“存储过程”文件夹中添加它。

那是防御性更高且更整洁的解决方案。但如果您更喜欢使用原始命令行,则至少要使用参数化查询,例如以下示例:

string sqlText = "SELECT columnName FROM Test_Attachments WHERE Project_Id =@PID1 AND [Directory] = @Directory";

 SqlCommand myCommand = new SqlCommand(sqlText, SqlConnection);
 myCommand.Parameters.AddWithValue("@PID1", 12);
 myCommand.Parameters.AddwithValue("@Directory", "testPath");

这是避免将SQL注入代码的方法。 您也可以使用finally块进行紧密连接:

    finally
    {
        command.Connection.Close();
    }

答案 1 :(得分:0)

谢谢你们的帮助。奥列格(Oleg)也感谢您的建议。我所做的是这样:

qSQL = "INSERT INTO " + tableName + " EXEC [LINKEDSERVER\\LINKED].[Data_Base_Name]." + spName;
using (SqlConnection _connection = new SqlConnection(connectionString))
{
            try
            {
                    command = new SqlCommand();
                    command.Connection = _connection;
                    command.Connection.Open();
                    command.CommandText = _qSQL;
                    command.CommandTimeout = 300; //Because it takes long
                    SqlTransaction transaction;
                    transaction = connection.BeginTransaction();
                    try
                    {
                        command.Transaction = _transaction;
                        command.ExecuteNonQuery();
                        transaction.Commit();
                        Debug.WriteLine("Done");
                    }
                    catch (SqlException e)
                    {
                        Debug.WriteLine("Exception [{0}:{1}]", e.Number, e.Message);
                        transaction.Rollback();
                    }
            //close connection
                    command.Connection.Close();
                }
                catch (SqlException e)
                {
                    command.Connection.Close();
                    Debug.WriteLine("exception error number: " + e.Number + ": " + e.Message);
                }
            }
}

如果您有任何改善建议,请告诉我。