【问题标题】:PHP mssql_query delete, create and select from #temp tablePHP mssql_query 从#temp 表中删除、创建和选择
【发布时间】:2017-06-19 15:39:36
【问题描述】:

我正在尝试:

  1. 如果存在临时表,请删除它。
  2. 使用选定的数据创建一个临时表。
  3. 从临时表中选择。

我在第 57 行收到“解析错误:C:\xampp\htdocs\test.php 中的解析错误。

任何帮助将不胜感激!

简短信息:

  • PHP 版本 5.2.9
  • MS SQL 2008 R2
  • 在 MS SQL 中执行的查询按预期工作

PHP 代码如下:

$query = "IF OBJECT_ID('tempdb..#temp') IS NOT NULL DROP TABLE #temp"
$result = mssql_query($query);

$query = "
SELECT *
INTO #temp
FROM (SELECT ROW_NUMBER() OVER (PARTITION BY key
      ORDER BY moment desc) AS Seq, *
FROM  reportstable) t
WHERE Seq = 1
and moment between '$_GET[od] $time' and '$_GET[do] $time1'"
$result = mssql_query($query);

$query = "select * from #temp"
$result = mssql_query($query);

提前致谢!

【问题讨论】:

  • 第 57 行是哪一行?
  • mysql 已从 php 7 中完全删除,并且已弃用 php 5.5 及更高版本,因此请避免使用它,使用 mysqli 或 PDO

标签: php sql sql-server temp-tables


【解决方案1】:

这不会像所写的那样工作,原因有几个。

  1. 您在此处使用的临时表仅对当前会话是本地的。换句话说,#temp 在您每次调用mssql_query() 之后都会消失。如果您需要一个临时表在多个上下文中持久存在,它必须是一个全局临时表 - ##temp
  2. 您的代码对 SQL 注入完全开放 - 您正在使用来自用户的未经处理的输入。这是一个巨大的安全漏洞,已经存在了 2 年,而且你一直在坚持。阅读 PDO 和参数化查询/准备语句。
  3. 您的查询可能格式不正确。构造后输出实际$query,并确保您的日期时间格式正确。

综上所述,假设您修复了 SQL 注入漏洞,那么在此处使用临时表是没有意义的,而且会浪费资源。以下内容就足够了:

$query = "
SELECT *
FROM (SELECT ROW_NUMBER() OVER (PARTITION BY key
      ORDER BY moment desc) AS Seq, *
FROM  reportstable) t
WHERE Seq = 1
and moment between '$_GET[od] $time' and '$_GET[do] $time1'"
$result = mssql_query($query);

【讨论】:

  • 嗨,我尝试了最简单的方法——通过 mssql studio 创建临时文件,然后简单地从 php 中进行选择,但没有成功。我还尝试了全球温度##。也没有成功。知道可能是什么问题吗?
  • @SpiroK 完全消除了临时表,并将您的代码简化为我在此处发布的内容。并输出$query,以便您可以看到发送到 SQL Server 的 实际 查询。我怀疑此查询的构造不正确,这导致了您的问题。
  • 我做对了。 echo $query 向我展示了我在那里遇到问题 - 失踪;在查询语句的末尾。现在我可以删除一个临时表(如果存在),创建一个临时表并从临时表中查询。我注意到你,mssql_fetch_array 和 mssql_num_rows 不起作用 - 抛出错误“提供的参数不是有效的 MS SQL 结果资源”,如果我循环遍历它,我可以计算它并回显每一行。
【解决方案2】:

基于alroc 建议的可行解决方案:

由于缺少分号而引发解析错误。并且 ## 必须始终存在才能查询表。

// to delete the temp table
$query = "IF OBJECT_ID('tempdb..##temp') IS NOT NULL DROP TABLE ##temp";
$result = mssql_query($query);

// to initialize the temp table
$query = "
SELECT *
INTO ##temp
FROM (SELECT ROW_NUMBER() OVER (PARTITION BY test_key
      ORDER BY test_moment desc) AS Seq, *
FROM  reports_table) t
WHERE Seq = 1
and test_moment between '$_GET[od] $time' and '$_GET[do] $time1'";
$result = mssql_query($query);

// to query the temp table
select test_key
from ##temp
where x = 0
and y = 1
and z = 3

附言以上仅在同一会话中有效。如果您在同一时间从不同来源调用同一页面,则会因为尝试删除临时表而引发错误。

【讨论】:

    猜你喜欢
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    相关资源
    最近更新 更多