我正在尝试从Perl执行一个过程并将结果存储在一个文本文件中(在Windows上)。我正在使用DBI fetchrow_hashref()来获取行结果。我尝试执行的存储过程返回超过500万行。我想知道功能"幕后花絮" - 特别是在这期间发生的事情 fetchrow_hashref()调用。例如Perl执行该过程,该过程返回所有受影响的行,将其保存在池中(在数据库端或调用机器端?),然后Perl逐个从结果集中选择行。它会以这种方式发生吗?
答案 0 :(得分:0)
这是一个很难回答的问题,因为您没有说过您使用的是哪种Perl数据库驱动程序。我假设您在此答案中使用DBD :: ODBC和MS SQL Server ODBC驱动程序。
当您调用SQL调用该过程时,ODBC驱动程序将其发送到解析过程的MS SQL Server。在调用execute时,程序启动(如何在程序中取得进展取决于很多事情)。假设您的过程中的第一件事是选择将为查询创建一个游标,MS SQL Server将开始将行发送回ODBC驱动程序(它使用TDS协议)。同时DBD :: ODBC将对驱动程序进行ODBC调用,告诉它有结果集(SQLNumResultCol返回非零值)。然后DBD :: ODBC将在驱动程序中查询结果集中列的类型并绑定它们(SQLBindCol)。
每次调用fetchrow_hashref时,DBD :: ODBC都会调用SQLFetch,ODBC驱动程序将从套接字读取一行并将数据复制到绑定缓冲区。
这里有重要的事情需要实现。大多数情况下,MS SQL Server最初会向套接字写入大量行,即使ODBC驱动程序可能尚未读取它们。因此,如果您关闭语句,驱动程序必须从套接字读取大量行并将其丢弃。如果您使用非标准游标或在驱动程序中启用多个活动语句,则会一次将一个行发送回驱动程序,以便ODBC驱动程序可以要求服务器向前移动,向后移动结果集或从行请求行结果集1然后结果集2。
在使用诸如是否启用nocount之类的过程时,还有其他方面有点不寻常,并且您使用SQLMoreResults(odbc_more_results)继续执行过程语句。此外,在SQLMoreResults返回false之前,过程中的输出参数不可用。
您可能会发现[{3}}感兴趣的Multiple Active Statements (MAS) and DBD::ODBC或may some of the other articles。您可能还想阅读有关TDS协议的内容。