首页 新闻 搜索 专区 学院

sqlserver查询,控制台应用程序

0
[已解决问题] 解决于 2018-08-24 11:36

sqlserver数据库中某个表写了一个触发器:

USE [MNRYMAS]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[tritest]
ON [dbo].[Equip_LAirCompressor]
after insert 
AS 
BEGIN

declare @newID varchar(50),@Result varchar(100)
      
       select @newID=ID from inserted

    set @Result = 'D:\Debug\Test_GetData.exe "'+@newID+'"'
    EXEC master..xp_cmdshell @Result

    SET NOCOUNT ON;



END

该触发器是数据库添加数据时调用一个外部的exe(控制台应用程序)。传入参数就是当前插入数据的id。控制台应用程序根绝这个id去查询这条插入的数据进行操作。

具体得查询方式如下:

if (args.Count() <= 0)
                {
                    return;
                }
                //string ID = "151055";
                string ID = args[0];
                using (SqlConnection conn = new SqlConnection(sql_local))
                {
                    string str_sql = "select * from [MNRYMAS].[dbo].[Equip_LAirCompressor] where ID = '" + ID + "'";using (SqlCommand cmd = new SqlCommand(str_sql, conn))
                    {
                        conn.Open();
                        //cmd.CommandTimeout = int.MaxValue;
                        SqlDataReader read = cmd.ExecuteReader();                        
                        while (read.Read())
                        {

                            double OldRoomPressure = read["OldRoomPressure"] == null ? 0 : double.Parse(read["OldRoomPressure"].ToString());
                            
                            double NewRoomPressure = read["NewRoomPressure"] == null ? 0 : double.Parse(read["NewRoomPressure"].ToString());
                           
                            double CoolingWaterTemp = read["CoolingWaterTemp"] == null ? 0 : double.Parse(read["CoolingWaterTemp"].ToString());
                            
                            double IsWarning = read["IsWarning"] == null ? 0 : double.Parse(read["IsWarning"].ToString());
                            
                            string CreateTime = read["CreateTime"].ToString();
                            
                           //其他操作

                        }
                    }
                }

 

但是,当把ID当参数传入应用程序时,直接到 

SqlDataReader read = cmd.ExecuteReader();   这句就会报错,错误:Timeout expired. 

如果按照上面ID的注释方式传入(

string ID = "151055";),直接在程序中吧参数写入进行测试的话,就没有问题。

崩溃了,就是一个是传入的,一个是写死的,传入就不行呢?

参数是可以传进去的。

1sa2sa的主页 1sa2sa | 菜鸟二级 | 园豆:289
提问于:2018-08-16 11:04
< >
分享
最佳答案
0

Console.WriteLine(ID) 打印一下传入的 ID 值看是否有问题

奖励园豆:5
dudu | 高人七级 |园豆:37797 | 2018-08-16 11:10

看了,没有问题。到sql语句都是没有问题得。就是到了cmd.ExecuteReader();这一句就报错了。

很是纳闷,搞了快一天了。

1sa2sa | 园豆:289 (菜鸟二级) | 2018-08-16 11:11

我把ID输出了,也把Sql语句输出来看了,都是正常的。可是执行查询的时候就不行了。

1sa2sa | 园豆:289 (菜鸟二级) | 2018-08-16 11:13

这是我记录下来的日志。参数穿进去了,这样看sql语句也是没错的。执行不了查询。。。

1sa2sa | 园豆:289 (菜鸟二级) | 2018-08-16 11:19

@1sa2sa: 上面的代码看着不舒服,而且有2个问题:1)后SQL注入漏洞;2)SqlDataReader没有关闭,稍微修改了一下

using (SqlConnection conn = new SqlConnection(sql_local))
{
    string str_sql = "select * from [MNRYMAS].[dbo].[Equip_LAirCompressor] where ID=@ID";
    using (SqlCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = str_sql;
        cmd.Parameters.AddWithValue("@ID", ID);
        conn.Open();
        //cmd.CommandTimeout = int.MaxValue;
        using (SqlDataReader read = cmd.ExecuteReader())
        {
            while (read.Read())
            {
                double OldRoomPressure = read["OldRoomPressure"] == null ? 0 : double.Parse(read["OldRoomPressure"].ToString());

                double NewRoomPressure = read["NewRoomPressure"] == null ? 0 : double.Parse(read["NewRoomPressure"].ToString());

                double CoolingWaterTemp = read["CoolingWaterTemp"] == null ? 0 : double.Parse(read["CoolingWaterTemp"].ToString());

                double IsWarning = read["IsWarning"] == null ? 0 : double.Parse(read["IsWarning"].ToString());

                string CreateTime = read["CreateTime"].ToString();

                //其他操作
            }
        }
    }
}
dudu | 园豆:37797 (高人七级) | 2018-08-16 11:26

@dudu: 谢谢。我这个是先进行方便测试用的,就写的比较粗糙。代码是存在一些问题。

但是,传入参数就无法进行查询,这个是什么原因呢?上面的图就是直接输出的id和sql语句,看着是正确的,但是就是查不出来,这个很是不解。

1sa2sa | 园豆:289 (菜鸟二级) | 2018-08-16 11:32

@1sa2sa: 直接在数据库执行同样的SQL语句正常吗?

dudu | 园豆:37797 (高人七级) | 2018-08-16 11:46

@dudu: 正常的。直接执行这条sql语句能正常查出来数据。

1sa2sa | 园豆:289 (菜鸟二级) | 2018-08-16 12:01

@1sa2sa: 问题应该与在触发器中查询刚插入的记录有关,你可以试试把 select @newID=ID from inserted 改为一个已经存在的 ID

dudu | 园豆:37797 (高人七级) | 2018-08-16 12:16

@dudu: 我直接 set @newID= 151060,这样写死id的值就可以。但是,触发器中写的是after insert啊。而且我是想实现数据插入是触发外部程序。这样的话,应该怎么办呢?

1sa2sa | 园豆:289 (菜鸟二级) | 2018-08-16 13:35

@dudu: 还有疑问是,触发器端是传了一个参数到外部程序中,外部程序只是接收了一个参数,为什么 select @newID=ID from inserted 这样会影响外部程序呢?而且是id的值已经传了过去。

1sa2sa | 园豆:289 (菜鸟二级) | 2018-08-16 13:38

@1sa2sa: 试试在控制台程序中查询数据库之前 Sleep 一会

dudu | 园豆:37797 (高人七级) | 2018-08-16 14:00

@dudu:刚才我也这么想,然后试了一下,sleep了5秒,但是结果还是不行。

不过发现,当外部程序执行完(到报错为止),才能查到数据。在外部程序停止时数据才插入到数据库中。我直接sleep10秒,不去查询数据,什么都不做。当外部程序执行完这十秒,数据才进入到数据库中。

这种情况的话,想在外部程序中根据id查询这条数据,应该是不行的了。

1sa2sa | 园豆:289 (菜鸟二级) | 2018-08-16 14:09

@1sa2sa: 建议换一种不通过触发器的方式

dudu | 园豆:37797 (高人七级) | 2018-08-16 14:13

@dudu: 应该是触发器执行完成之后,数据才会插入到数据库中。触发器执行完成需要外部程序先执行完。

1sa2sa | 园豆:289 (菜鸟二级) | 2018-08-16 14:18

@1sa2sa: 是的,就是这个原因

dudu | 园豆:37797 (高人七级) | 2018-08-16 14:33
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册