通过C#从表值函数(MSSQL)中选择数据会导致CREATE FUNCTION语句

时间:2019-01-24 11:58:13

标签: c# sql-server

我正在使用C#(.net 4.6.1)访问MSSQL 2018数据库。 有时当我从表值函数中选择数据时,(C#)程序似乎停止了,当我查看``运行查询''时,有一个挂起的查询创建了我要从中选择数据的函数(CREATE FUNCTION ... ..)。

这是我如何看待正在运行的查询

SELECT 
    syp.spid AS SesID
    ,syp.hostname
    ,syp.program_name
    ,syp.loginame
    ,sqltext.TEXT
    ,syp.login_time
    ,req.session_id
    ,req.status
    ,req.command
    ,SUM(req.cpu_time) AS cpu_time
    ,SUM(req.total_elapsed_time) AS total_elapsed_time
FROM DB.sys.dm_exec_requests req
CROSS APPLY DB.sys.dm_exec_sql_text(sql_handle) AS sqltext
INNER JOIN DB.sys.sysprocesses syp ON syp.spid = req.session_id
WHERE loginame <> ''
GROUP BY
    syp.spid 
    ,syp.hostname
    ,syp.program_name
    ,syp.loginame
    ,sqltext.TEXT
    ,syp.login_time
    ,req.session_id
    ,req.status
    ,req.command

我在C#中选择数据的方式如下:

    SqlCommand command = new SqlCommand("SELECT TOP 1 * FROM DB.._f_po_lines(@refRecHead) a ", conn);
    command.Parameters.AddWithValue("@refRecHead", refRecHead);

    using (SqlDataReader reader = command.ExecuteReader())
    {
        while (reader.Read())
        { .....

我试图通过事件探查器监视db活动,但是我在那里看不到CREATE FUNCTION语句(也许是因为它是隐藏的,但是我没有找到如何通过事件选择显示这些语句的方法),所以我我无法确定每次我从表值函数中选择数据时是否会发生这种情况。

现在,使(C#)程序再次起作用的唯一解决方案是在Management Studio中删除该功能并重新创建它。

我希望我能提供所有相关信息并有一些疑问: -从中选择数据时,MSSQL重新创建函数是否符合预期行为? -如果没有,发生这种情况的原因可能是什么? -如果可以,我该如何加快速度,以使(C#)程序不会减速到达到超时限制的程度?

edit :(简化的)函数看起来像这样(不太有趣,只是选择数据,但是我发现使用C#中的函数更容易)

ALTER FUNCTION [dbo].[_f_po_lines] (@RefRecHead bigint) RETURNS @ret TABLE

(
    RowNr int
)

AS

BEGIN
    INSERT INTO @ret

    SELECT 
        t.RowNr
    FROM DB..PURCHTABLE t
    WHERE 
        t.REFRECID = @RefRecHead

    RETURN
END

1 个答案:

答案 0 :(得分:0)

由于@JeroenMostert,我发现在“运行查询”输出中看到的查询文本实际上并不是从函数中选择数据时发生的事情。 所以我的第一个问题得到了解答,现在我只需要找出阻止该函数返回数据的内容即可。

现在,我已将实际函数更改为内联表值函数(因为性能更好),并将监视是否再次发生了挂起查询的问题。 如果再次发生这种情况,我将尝试通过@DanGuzman的建议来找出阻止它的原因。

非常感谢!