无法使用准备好的语句插入日期

时间:2018-09-27 10:43:48

标签: php sql-server date pdo prepared-statement

我正在尝试在给定的月份/年份中的每一天进行多行INSERT。

如果循环仅运行一次,则一切正常。如果运行两次或更多次,则会引发以下错误:

  

SQLSTATE [22018]:强制转换规范的字符值:206 [Microsoft] [ODBC SQL Server驱动程序] [SQL Server]操作符类型冲突:文本与日期不兼容(SQLExecute [206]位于ext \ pdo_odbc \ odbc_stmt。 c:260)

如果我不准备日期,它也可以使用。我茫然...我做错什么了吗?这是我的代码:

$query = "INSERT INTO scp.schedule
    (record_create_date, associate_id, scheduled_date, shift_id, is_weekend)
    VALUES ";

for ($day_count = 1; $day_count <= $days_month; $day_count++)
{
    $day_count = sprintf("%02d", $day_count);

    $full_date = $year . "-" . $month . "-" . $day_count;

    // Check if date is weekend
    $weekend = (date("N", strtotime($full_date)) < 6) ? 0 : 1;

    $query .= "(GETDATE(), ?, ?, ?, ?), ";
    $params[] = $associate["associate_id"];
    $params[] = $full_date;
    $params[] = $shifts[0]["shift_id"];
    $params[] = $weekend;
}

// Remove the last comma and space
$query = substr($query, 0, -2);

$stmt = $db->prepare($query);
$stmt->execute($params);

我正在使用SQL Server 12+版本和PHP 7+版本。数据库中的列类型为DATE。

编辑:

这有效

INSERT INTO scp.schedule 
    (record_create_date, associate_id, 
     scheduled_date, shift_id, is_weekend) 
VALUES (GETDATE(), ?, ?, ?, ?)

这不是

INSERT INTO scp.schedule 
    (record_create_date, associate_id, 
     scheduled_date, shift_id, is_weekend) 
VALUES (GETDATE(), ?, ?, ?, ?), 
       (GETDATE(), ?, ?, ?, ?)

编辑2:

某些测试及其引发的错误。我也尝试使用'?'

$query .= "(GETDATE(), ?, DATEFROMPARTS(?, ?, ?), ?, ?), ";
// Also tried intval() and casting to int
$params[] = $year;
$params[] = $month;
$params[] = $day_count;
  

SQLSTATE [22018]:转换说明的字符值无效:206 [Microsoft] [ODBC SQL Server驱动程序] [SQL Server]操作数冲突:文本与int不兼容(SQLExecute [206]位于ext \ pdo_odbc \ odbc_stmt。 c:260)

$query .= "(GETDATE(), ?, CONVERT(date, ?), ?, ?), ";
  

SQLSTATE [22018]:强制转换规范的字符值:529 [Microsoft] [ODBC SQL Server驱动程序] [SQL Server]不允许从数据类型文本到日期的明确转换。 (位于ext \ pdo_odbc \ odbc_stmt.c:260的SQLExecute [529])

2 个答案:

答案 0 :(得分:1)

您可能会尝试避免使用DATEFROMPARTS()CONVERT() T-SQL函数将字符串作为SQL Server中日期字段的值传递。

<?
$query = "INSERT INTO scp.schedule
    (record_create_date, associate_id, scheduled_date, shift_id, is_weekend)
    VALUES ";

for ($day_count = 1; $day_count <= $days_month; $day_count++) {
    $day       = $day_count;
    $day_count = sprintf("%02d", $day_count);
    $full_date = $year . "-" . $month . "-" . $day_count;

    // Check if date is weekend
    $weekend = (date("N", strtotime($full_date)) < 6) ? 0 : 1;

    # Using DATETIMEFROMPARTS
    $query .= "(GETDATE(), ?, DATEFROMPARTS(?, ?, ?), ?, ?), ";
    $params[] = $associate["associate_id"];
    $params[] = $year;
    $params[] = $month;
    $params[] = $day;
    $params[] = $shifts[0]["shift_id"];
    $params[] = $weekend;

    # Using CONVERT
    /*
    $query .= "(GETDATE(), ?, CONVERT(date, ?), ?, ?), ";
    $params[] = $associate["associate_id"];
    $params[] = $full_date;
    $params[] = $shifts[0]["shift_id"];
    $params[] = $weekend;
    */
}

// Remove the last comma and space
$query = substr($query, 0, -2);
$stmt = $db->prepare($query);
$stmt->execute($params);

?>

如果不必在一条语句中插入整天,则可以考虑准备一次语句并在每次迭代中执行。 然后,如果发生错误,您将知道什么值引起了问题。

答案 1 :(得分:-1)

尝试使用trim代替substr

$query = trim(trim($query), ',');

内部trim将删除space,外部trim将删除,