【问题标题】:Creating MS SQL Temp Tables in SQLSRV PDO in PHP在 PHP 中的 SQLSRV PDO 中创建 MS SQL 临时表
【发布时间】:2015-09-22 10:07:06
【问题描述】:

通常在 asp.net 中,我可以一个接一个地运行许多查询来创建我的临时表。我们从很多表中提取,因此它具有巨大的速度优势。然后我会从 #999 中进行选择。

目标:

这是我在 asp.net 中的页面之一:

    sql.Append("Create Table #999 (SvID varchar(15) Default '', SvcID int Default ((0)), Value varchar(50) Default '', Store varchar(10) Default '', StoreID int Default ((0)), VisitDate varchar(100) Default '', Lead varchar(100) Default '',  LeadID int Default ((0)),ShipTo varchar(100) Default '', ShipToAddress varchar(300) Default '', Parts Varchar(5000) Default '', ShipToID int Default ((0)), ShipToType Varchar(50) Default '', ProjID int Default ((0)), DivID Int Default ((0)), Combined int Default ((0)), HasTime int Default ((0)), DateOK Int Default ((0))); ");

    //Insert StoreVisitID's
    sql.Append("Insert into #999 (SvID) Select Distinct ID from StoreVisit where projid =" + ProjID + "; ");

    //Update Store Visit Info
    sql.Append("Update #999 Set SVcID = sub.svcid, Store = sub.Store, StoreID = sub.StoreID, ProjID = sub.ProjID, LeadID = sub.TeamLeadID, VisitDate = sub.VisitDate, DivID = sub.DivID, Value = sub.Status from #999 h Join (select svcID, Store, StoreID, ProjID, ID, TeamLeadID, Convert(Varchar, Visitdate, 1) as VisitDate, DivID, Status  From StoreVisit where projid =" + ProjID + ") as sub on sub.id = h.svid; ");

    //Update Store Visit Lead
    sql.Append("Update #999 Set Lead = sub.Lead From #999 h Join ( Select id, FirstName + ' ' + LastName as Lead From Employee) as sub on sub.id = h.LeadID; ");

    //Update ShipToID, ShipToType
    sql.Append("Update #999 Set ShipToID = sub.ShipToID, ShipToType = sub.ShipToType From #999 h Join ( Select SviD, ShipToID, ShipToType from StoreVisit2) as sub on sub.svid = h.svid; ");

    //Ship To Other Employee
    sql.Append("Update #999 Set ShipTo = Sub.Lead + ' - Employee', ShipToAddress = sub.Address From #999 h  Join (Select id, FirstName + ' ' + LastName as Lead, Address + '. ' + Address2 + ', ' + City + ', ' + State as Address From Employee) as sub on sub.id = h.ShipToID Where ShipToType='E' and ShipToID <> 0; ");

问题:

在 php 中,我试图用准备好的语句做同样的事情。

Attempt1: 代码如下。我在第二次执行时收到无效对象 #ViewQuestionComments 错误。

Attempt2: 我尝试准备每个 sql,然后执行一次,但我在执行时遇到了同样的错误。

Attempt3: 我还尝试连接所有 sql 并在一个准备和执行语句中运行,但出现相同的错误。

关于如何正确执行此操作的任何建议?

这是我正在运行的代码。

        $sql = "IF OBJECT_ID('#ViewQuestionComments', 'U') IS NOT NULL DROP TABLE #ViewQuestionComments; Create Table #ViewQuestionComments (CommentID int default ((0)), UserID int default ((0)), Comment varchar(max)  default '', DateModified smalldatetime, UserName nvarchar(200) default '', Points int default ((0)))";
        $stmt = $PDO->prepare( $sql );
        $stmt->execute();
        $sql = "Insert Into #ViewQuestionComments (CommentID, UserID, Comment, DateModified)  select ID, UserID, Comment, DateModified from hanoncs_askme.hanoncs_hanoncs.Comments Where PostID=? and Status=1";
        $stmt = $PDO->prepare( $sql );
        $stmt->bindParam(1, $QuestionID);
        $stmt->execute();

        $sql = "Update #ViewQuestionComments Set UserName = m.UserName From #ViewQuestionComments c Left Join hanoncs_securelogin.hanoncs_hanoncs.members m on m.id = c.UserID";
        $stmt = $PDO->prepare( $sql );
        $stmt->execute();

        $sql = "Update #ViewQuestionComments set Points = (Select count(*) from hanoncs_askme.hanoncs_hanoncs.CommentVotes where PostID=c.CommentID) From #ViewQuestionComments c";
        $stmt = $PDO->prepare( $sql );
        $stmt->execute();

        $sql = "Select * from #ViewQuestionComments";
        $stmt = $PDO->prepare( $sql );
        $stmt->execute();
        $rows6 = $stmt->fetchAll(PDO::FETCH_BOTH);

【问题讨论】:

    标签: php sql-server pdo


    【解决方案1】:

    使用存储过程,没那么难:

    CREATE PROC updateQuestion ()
     AS
     BEGIN
        BEGIN TRANSACTION
    
            IF Object_id('#ViewQuestionComments', 'U') IS NOT NULL DROP TABLE #viewquestioncomments;
            CREATE TABLE #viewquestioncomments 
                         ( 
                                      commentid INT DEFAULT ((0)), 
                                      userid    INT DEFAULT ((0)), 
                                      comment   VARCHAR(max) DEFAULT '', 
                                      datemodified SMALLDATETIME, 
                                      username NVARCHAR(200) DEFAULT '', 
                                      points   INT DEFAULT ((0)) 
                         );
                         INSERT INTO #viewquestioncomments 
                        ( 
                                    commentid, 
                                    userid, 
                                    comment, 
                                    datemodified 
                        ) 
            SELECT id, 
                   userid, 
                   comment, 
                   datemodified 
            FROM   hanoncs_askme.hanoncs_hanoncs.comments 
            WHERE  postid=? 
            AND    status=1;
            UPDATE #viewquestioncomments 
            SET       username = m.username 
            FROM      #viewquestioncomments c 
            LEFT JOIN hanoncs_securelogin.hanoncs_hanoncs.members m 
            ON        m.id = c.userid;
            UPDATE #viewquestioncomments 
            SET    points = 
                   ( 
                          SELECT Count(*) 
                          FROM   hanoncs_askme.hanoncs_hanoncs.commentvotes 
                          WHERE  postid=c.commentid) 
            FROM   #viewquestioncomments c;
            SELECT * 
            FROM   #viewquestioncomments";
    
         IF @@ERROR != 0
            ROLLBACK TRANSACTION
            ELSE
                COMMIT TRANSACTION
     END
    
    GO
    

    用法:

    $stmt= $PDO->prepare('EXEC updateQuestion');
    $stmt->execute();
    

    【讨论】:

    • 我对我的问题进行了编辑。请往下看。
    • 谢谢,我试过了:SET NOCOUNT ON;。但仍然得到错误。
    • This: 'EXEC [hanoncs_hanoncs].[CommentsTemp] @QuestionID = 1' 在管理工作室中完美运行。
    • 它会返回任何东西吗,你在获取吗
    • 我得到了这个错误:$rows6 = $stmt->fetch(PDO::FETCH_BOTH);
    【解决方案2】:

    不管你的高级程序员不喜欢他们,我经常在有意义的地方使用存储过程。

    根据我的第一手经验,大多数 sql 活动(不是单个选择、更新、插入或删除语句)都可以从存储过程中受益。与工具箱中的任何工具一样,这取决于您在做什么。当我构建临时表时,它是在存储过程中完成的,因为它是一个复杂的操作,并且经常涉及大量的 sql。

    在您的示例中,检查对象是否存在,删除它,构建一个新的 db 对象,添加数据,然后将数据提取出来,恕我直言,这是一系列强烈建议使用存储过程的操作。其他人可能会争论某些层的数据访问对象。无论如何,您确实希望封装它以保持您的产品可维护。存储过程做得很好。与一次发送一个组件 sql 语句相比,它们还需要更少的网络流量。它们通常也会比内联 sql 运行得更快,不仅仅是因为网络延迟,数据库所做的许多事情之一就是为它运行的任何 sql 生成执行计划,虽然准备好的语句有帮助,但存储过程的帮助更大。到目前为止,据我所见,人们对它们最大的抱怨是 sql 不像 java、C#、Objective C 或任何其他语言那样健壮的编程语言。人们将其他事情列为缺点,但 imo 能够轻松高效地完成您需要做的事情是最重要的。

    再次重申,它们是工具箱中的工具之一,并且与任何工具一样,有时间和地点使用它们。但是不要单方面解雇他们,那将是一个错误。就个人而言,多年来我已经很好地使用了它们,并且随着我对 sql 的能力和知识的增加,我发现它们更好的用途。了解所有工具。

    查看Creating Stored Procedures 的 t-sql 文档 如果您想更多地了解存储过程的优缺点,那么互联网上就充满了这些,等等。这里有几个链接。

    Determine when to use stored procedures vs. SQL in the code

    Why use Stored Procedures?

    Stored Procedures Are Evil

    谷歌“存储过程与内联 sql”,你会得到更多。请记住,适合工作的正确工具。

    【讨论】:

    • 是的,我的标题也是 MS SQL。我去看看。
    • 知道版本将允许直接链接到该版本的文档。您仍然可以在点击链接后切换版本。
    • 感谢您更新您的答案。我刚读到这个,programmers.stackexchange.com/questions/158534/…,答案和 cmets 对使用存储过程有一些很好的论据。因为我们没有 DBA,而且我不是最擅长调整 SQL 的。我们也有多名程序员。所以我想我可能只是将 SQL 保留在代码中。
    • 我希望那里的系统设计人员对经常使用/重用的 sql 进行某种形式的封装。如果没有存储过程,那么至少有一组类。如果项目是任何规模并且有人关心他们正在设计什么,那么为了将来的可维护性,这种封装是必须的。祝你好运,并强烈建议你利用一切机会尽可能扩展你在 sql 领域的技能。用得好,它可以成为一个强大的工具。
    • @Hanoncs 我同意 WillG sp 是解决这种情况的方法,您查找的问题是关于放置不可取的业务逻辑。但对于多个查询,这是需要的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 2013-05-26
    • 2011-03-28
    • 2013-09-24
    • 2012-03-28
    • 2011-11-03
    • 1970-01-01
    相关资源
    最近更新 更多