【问题标题】:Copying data from one column to another but changing datatype using SQL in PHP在 PHP 中使用 SQL 将数据从一列复制到另一列但更改数据类型
【发布时间】:2021-03-13 14:43:48
【问题描述】:

我正在尝试将一列数据(数字)复制到同一个表中的不同列 (VARCHAR)。似乎直接运行更新查询并将 varchar 列设置为 $_POST 列将是什么。问题是数字列将包含 5 个尾随零。我还需要将其重新格式化为副本中的 INT 类型。这是 PHP 中原始查询的副本:

try{
    $q = "UPDATE table1 SET text1 = " . $_POST["htmlinputfield"] . 
        " WHERE account_id = :aid AND fieldapplication_id = :fid";
    $stmt = $this->app->db->prepare($q);
    $stmt->execute(array(":fid"=>$this->app->fid,":aid"=>$this->app->aid));
} catch(exception $e){
    $this->app->logErroredQuery($e,$q);
    return $e->getMessage();
}

我尝试在 if 语句中使用 php 更改数据类型,然后坚持查询。也无法让它工作。看起来是这样的:

$htmlfield = $_POST["htmlinputfield"];
    
if(is_numeric($htmlfield)){
    (int)$htmlfield;
}else{
    (string)$htmlfield;
}
    
try{
    $q = "UPDATE table1 SET text1 = :htmlfield 
          WHERE account_id = :aid AND fieldapplication_id = :fid";
    $stmt = $this->app->db->prepare($q);
    $stmt->execute(array(":fid"=>$this->app->fid,
                        ":aid"=>$this->app->aid,
                        ":htmlfield"=>$htmlfield));
} catch(exception $e){
    $this->app->logErroredQuery($e,$q);
    return $e->getMessage();
}

这导致将所有结果更改为列的名称,而不是数据的副本。原始查询适用于除数字情况以外的所有情况。

我想这可能是 CAST 情况,但我的 SQL 能力不是很好。最终结果将是在 $_POST 中选择的任何数据库列都将被格式化为 int 或 varchar。任何帮助将不胜感激。

【问题讨论】:

  • 为什么!!!连接新值并在其余查询中使用参数。 HINT 参数是正确的走法
  • 有点困惑!你说你想将一列复制到另一列,那么 $_POST 到底有什么关系
  • 你是对的 Google mysql cast 然后你也可以阅读 MySQL 手册
  • $_POST 所做的是选择要复制的表中的列。

标签: php sql database


【解决方案1】:

使用$q = "UPDATE table1 SET text1 = " . $_POST["htmlinputfield"] 的第一个查询是需要完成的一般方式。您需要将列名直接插入到 SQL 字符串中,但是像这样盲目地使用来自 $_POST 的值是不安全的。在查询中使用$_POST["htmlinputfield"] 之前,您应该验证它是一个有效的列名。您可以使用白名单方法并根据 PHP 代码中可接受的列名数组对其进行检查。

第二种方式$q = "UPDATE table1 SET text1 = :htmlfield 不行,因为列名是标识符,不能绑定标识符,只能绑定值。

这部分:

$htmlfield = $_POST["htmlinputfield"];
    
if(is_numeric($htmlfield)){
    (int)$htmlfield;
}else{
    (string)$htmlfield;
}

真的没有意义,因为如果我理解正确,$_POST["htmlinputfield"] 是列名,并且在 PHP 中使用 is_numeric() 不会告诉你该列的数据类型是什么,它只是检查列名是否为数字。

我认为解决此问题的一种方法是检查更新查询中的值是否为数字,如果是则删除小数位,否则按原样处理。所以首先验证我上面提到的发布的列名。完成后,您可以像这样在查询中安全地使用它:

"UPDATE table1 SET text1 = CASE
   WHEN `$column_name` REGEXP '^[0-9]+(\.[0-9]+)?$'
   THEN FLOOR(`$column_name`)
   ELSE `$column_name`
 END
 WHERE account_id = :aid AND fieldapplication_id = :fid"

检查一个值是否为数字有不同的方法,将值转换为int有不同的方法,但我认为大体思路还是这样的。

【讨论】:

    【解决方案2】:

    在上一个示例中尝试以下查询:

    UPDATE table1 SET text1 = CAST(:htmlfield AS UNSIGNED) WHERE account_id = :aid AND fieldapplication_id = :fid
    

    【讨论】:

      猜你喜欢
      • 2015-05-14
      • 2016-03-15
      • 1970-01-01
      • 1970-01-01
      • 2020-11-03
      • 2021-08-26
      • 2012-07-19
      • 2021-11-28
      • 2010-11-22
      相关资源
      最近更新 更多