1

我有这样的查询:

$sql = "UPDATE test_accs SET 
    acc_owner = '$owner_id', 
    acc_policy_version = '$version', 
    acc_policy_last_update = '$approved', 
    acc_policy_next_update = '$renewed' 
        WHERE acc_id = '1'";

现在,web folmular 上的所有这些值都是可选的,一个可以设置这些值中的一个,两个,左右。现在,在我提交表单后,它会像这样进入查询:

UPDATE test_accs SET acc_owner = '2', acc_policy_version = '1.2', acc_policy_last_update = '2012-12-19', acc_policy_next_update = '2012-12-18' WHERE acc_id = '1'

它仅在我提交表单中的所有值时才有效。即使没有发送所有值(例如其中一个值),您能否告诉我它如何工作?

当我设置一个值(例如政策版本)时,它看起来像这样:

UPDATE test_accs SET acc_owner = '', acc_policy_version = '1.2', acc_policy_last_update = '', acc_policy_next_update = '' WHERE acc_id = '1'

它不工作。

可能是 acc_owner 表值的原因?

#1366 - Incorrect integer value: '' for column 'acc_owner' at row 1

谢谢指教。

形式:

echo '<td>Change owner: <select name="owner_id" onchange="showUser(this.value)" style="font-size:9px"><option value="">Select a person:</option>';
    while($owners = mysql_fetch_array($owners_query)) { echo '<option value="'.$owners['id'].'">'.$owners['surname'].' '.$owners['name'].'</option></h2>'; } echo '</select></td>';
    echo "<td><input name='version' style='width:50px;text-align:center' placeholder='0.0' /></td>";
    echo "<td><input name='approved' class='datepicker_all' readonly='readonly' style='text-align:center' placeholder='1999-01-01' /></td>";
    echo "<td><input name='renewed' class='datepicker_all' readonly='readonly' style='text-align:center' placeholder='1999-01-01' /></td>";
4

6 回答 6

6

实现此目的的一种方法是在 SQL 语句中使用表达式来测试提供的值是否为空字符串。如果提供的值为空字符串,则使用列的当前值作为分配给该列的值。否则,将提供的值分配给列。

在下面的示例中,提供的每个值都必须在语句中包含两次:一次在条件测试中,然后再次作为条件测试的可能结果。

这个说法:

UPDATE test_accs
   SET acc_owner              = IF('2'='',acc_owner,'2')
     , acc_policy_version     = IF('1.2'='',acc_policy_version,'1.2')
     , acc_policy_last_update = IF('2012-12-19'='',acc_policy_last_update,'2012-12-19')
     , acc_policy_next_update = IF('2012-12-18'='',acc_policy_next_update,'2012-12-18')
 WHERE acc_id = '1'

等效于问题中的第一个 UPDATE 语句,因为它将所有四列的值设置为新的指定值。

这个说法:

UPDATE test_accs
   SET acc_owner              = IF(''='',acc_owner,'')
     , acc_policy_version     = IF('1.2'='',acc_policy_version,'1.2')
     , acc_policy_last_update = IF(''='',acc_policy_last_update,'')
     , acc_policy_next_update = IF(''='',acc_policy_next_update,'')
 WHERE acc_id = '1'

仅更改acc_policy_version列的值,其他三列的值将保持不变。

这不一定是最好的方法,但在某些情况下是可行的。

也可以创建一个表达式,要求在语句中指定每个提供的值一次,尽管我认为这些表达式不太直观:

   SET acc_owner          = COALESCE(NULLIF( ''     ,''),acc_owner         )
     , acc_policy_version = COALESCE(NULLIF( '1.2'  ,''),acc_policy_version)

这基本上与上面的例子做同样的事情。

如果提供的值等于 ''(就像acc_owner上面示例中的那样),则 NULLIF 表达式将返回 NULL。COALESCE 函数本质上会导致 NULL 值被跳过,并且列的当前值将保持不变(列的当前值分配给列。)

如果提供的值不等于 ''(就像acc_policy_version上面示例中的那样),则 NULLIF 表达式将返回提供的值。COALESCE 函数将获取该值,并将其分配给列。

于 2012-12-12T17:14:57.127 回答
1

检查是否acc_owner为空并将其设置为零是一种选择,如果列应该包含整数,则不能插入空格 - 或者除非您有 int 值,否则不要进行更新

1:

if(strlen($acc_owner)==0){
  $acc_owner=0;

}

2:

 if(is_int($acc_owner)){
  //update it
  }
于 2012-12-12T16:58:23.800 回答
1

整数字段的值是必需的吗?如果不是,则检查设置的 GET/POST 值,如果为空,则不要将其包含在更新语句中。

if(isset($_GET['acc_id'])) {
    $acc_id = $_GET['acc_id'];
    $sql = "UPDATE test_accs SET ";

    if(isset($_GET['version'])) {
       $version = $_GET['version'];
       $sql = $sql . "acc_policy_version = " . $version . ",";
    }

    if(isset($_GET['owner_id'])) {
       $owner_id = $_GET['owner_id'];
       $sql = $sql . "acc_owner = " . $owner_id . ",";
    }

    $sql = $sql .
        "acc_policy_last_update = '$approved', 
        acc_policy_next_update = '$renewed' 
        WHERE acc_id = " . $acc_id;

    //Execute SQL
    echo "successfully updated " . $acc_id;
} else { 
    echo "invalid acc_id"; 
}
于 2012-12-12T17:04:58.173 回答
0

1 - 将您的 $owner_id 转换为 int 类型

$owner_id = (int)$owner_id;

2 - 仅当值 > 0 时才使用条件更新此字段

$sql = "UPDATE test_accs SET " . 
        ($owner_id > 0 ? "acc_owner = '$owner_id', " : "") .
        "acc_policy_version = '$version', " .
        "acc_policy_last_update = '$approved', " . 
        "acc_policy_next_update = '$renewed' " .
        "WHERE acc_id = '1'";

注意:小心,您的变量似乎没有正确安全,并且您有 mysql 注入的风险。请参阅http://php.net/manual/fr/mysqli.real-escape-string.php

而且,也许您应该考虑为您的 mysql 开发或任何 orm 使用 PDO php 扩展 (http://fr2.php.net/manual/en/intro.pdo.php)?

于 2012-12-12T17:19:55.360 回答
0

您可以根据它们各自的数据类型使用默认值初始化保存可选字段值的变量。

请参考下面提到的代码片段。

      $owner_id=0;
      $version=0;
      $approved='';
      $renewed='';

     if($_SERVER['REQUEST_METHOD']=='POST')
     {
          extract($_POST);
      }

             $sql = "UPDATE test_accs SET 
acc_owner = '$owner_id', 
acc_policy_version = '$version', 
acc_policy_last_update = '$approved', 
acc_policy_next_update = '$renewed' 
    WHERE acc_id = '1'";
于 2012-12-12T17:25:34.230 回答
0

您应该验证来自 html 表单的所有值。比,如果你的 mysql 字段可以为 NULL,只需将 NULL 设置为 php var:

if (strlen($owner_id) == 0) {
    $owner_id = NULL;
    // OR 
    $owner_id = 0;
} else {
    $owner_id = addslashes($owner_id);
}

$sql = "UPDATE test_accs SET 
    acc_owner = '$owner_id', 
    acc_policy_version = '$version', 
    acc_policy_last_update = '$approved', 
    acc_policy_next_update = '$renewed' 
        WHERE acc_id = '1'";
于 2012-12-12T17:02:22.950 回答