Преобразовать строку в тип данных даты в SQL Сервер в PHP Laravel - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь получить продукт по идентификатору между указанным c диапазоном дат, но проблема, с которой я сталкиваюсь:

  1. дата находится в строковом формате
  2. по какой-то странной причине даты хранятся в базе данных с неполной меткой времени (например: '12-04-2020 12:21 '), от которой я пытаюсь избавиться

Используя Laravel Запрос Eloquent ниже работает без последней строки (AND ...), которая является моей попыткой выполнить преобразование даты.

Я могу решить эту проблему с помощью MySQL, но текущая задача - использовать SQL Сервер не совсем уверен, что здесь пошло не так, любая помощь очень заметна.

$id = 2;
$from = '01-03-2020';
$to = '01-05-2020';



            $products = DB::select("SELECT DISTINCT
                                products.PRODUCT_ID,
                                products.PRODUCT_NAME,
                                TRANSACTIONS_DTL.PRODUCT_ID,
                                TRANSACTIONS_DTL.TRANS_ID,
                                TRANSACTIONS_DTL.PRODUCT_VALUE,
                                TRANSACTIONS_HD.TRANS_ID,
                                TRANSACTIONS_HD.TRANS_DATE
                             FROM
                             products
                                INNER JOIN TRANSACTIONS_DTL ON products.PRODUCT_ID = TRANSACTIONS_DTL.PRODUCT_ID
                                INNER JOIN TRANSACTIONS_HD ON TRANSACTIONS_DTL.TRANS_ID = TRANSACTIONS_HD.TRANS_ID
                             WHERE
                                products.PRODUCT_ID = $id 
                            AND TRANSACTIONS_HD.TRANS_DATE > CONVERT(date,'$from') AND TRANSACTIONS_HD.TRANS_DATE < CONVERT(date,'$to')
        ");

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Хорошо, перечитав это, вы увидите, что вместо этого вам нужно сделать следующее:

AND CAST(SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 7, 4)
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 4, 2)
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 1, 2) 
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 12, 5)
        + ':00' AS datetime2) > '$from'
AND CAST(SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 7, 4)
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 4, 2)
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 1, 2) 
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 12, 5)
        + ':00' AS datetime2) < '$to'

Wi sh, что было проще. (Использование псевдонима для таблицы сделает ее менее плотной)

На SQL сервере обратите внимание, что ваши $ from и $ to должны быть просто строками в формате «ГГГГММДД», например, «20201231». Это будет работать независимо от того, какой тип данных даты используется, а также независимо от языка и региональных настроек. Вы просто указываете их как строку, вам не нужно их приводить.

ПРИМЕЧАНИЕ. Я также предположил, что формат даты в вашей таблице - ДД-ММ-ГГГГ, потому что я не могу сказать, какой Кстати, они взяты из ваших примеров. Если ваш местный формат даты - ММ-ДД-ГГГГ (т.е. даты в США), используйте вместо этого этот код:

AND CAST(SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 7, 4)
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 1, 2)
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 4, 2) 
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 12, 5)
        + ':00' AS datetime2) > '$from'
AND CAST(SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 7, 4)
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 1, 2)
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 4, 2) 
        + SUBSTRING(TRANSACTIONS_HD.TRANS_DATE), 12, 5)
        + ':00' AS datetime2) < '$to'
0 голосов
/ 06 мая 2020

Кажется, что вы сохраняете datetime значения в виде текста в своей таблице (если возможно, попробуйте исправить эту проблему). Итак, чтобы найти решение вашей проблемы, вы можете попробовать следующее:

  • Преобразуйте значения в столбце TRANSACTIONS_HD.TRANS_DATE, используя соответствующий стиль .
  • Используйте однозначный формат (yyyymmdd) для дат в переменных $from и $to.
  • Используйте привязки параметров в операторах SQL, чтобы обеспечить защиту от SQL инъекции.

Пример (на основе вашего кода):

...

$id = 2;
$from = '20200301';
$to = '20200501';

$products = DB::select("
    SELECT DISTINCT
        products.PRODUCT_ID,
        products.PRODUCT_NAME,
        TRANSACTIONS_DTL.PRODUCT_ID,
        TRANSACTIONS_DTL.TRANS_ID,
        TRANSACTIONS_DTL.PRODUCT_VALUE,
        TRANSACTIONS_HD.TRANS_ID,
        TRANSACTIONS_HD.TRANS_DATE
    FROM products
    INNER JOIN TRANSACTIONS_DTL ON products.PRODUCT_ID = TRANSACTIONS_DTL.PRODUCT_ID
    INNER JOIN TRANSACTIONS_HD ON TRANSACTIONS_DTL.TRANS_ID = TRANSACTIONS_HD.TRANS_ID
    WHERE 
        (products.PRODUCT_ID = ?) AND 
        (CONVERT(date, TRANSACTIONS_HD.TRANS_DATE, 105) > CONVERT(date, ?)) AND 
        (CONVERT(date, TRANSACTIONS_HD.TRANS_DATE, 105) < CONVERT(date, ?))
", [$id, $from, $to]);

...
...