SQLite3connection: near "(": синтаксическая ошибка в Lazarus - PullRequest
0 голосов
/ 02 февраля 2020

У меня есть оператор отклонения SQL, но я обнаружил ошибку при запуске. Я исследовал много смежных тем, чтобы найти решение, но я еще не решил его.

SQLite3connection: near "(": синтаксическая ошибка

Я надеюсь получить помощь от всех.

strSQL:='SELECT Mathang.Stt
         ,Mathang.Mahang
         , Mathang.Tenhang
         ,SUM(CASE 
                WHEN Xuatnhap.Loaiphieu="N" 
                     AND SQLQuery1.FieldByName("Ngay").asString <= StrToDate(Edit1.Text) 
                THEN Xuatnhap.Soluong  
                ELSE 0  
              END) AS Tongnhap
         ,SUM(CASE
                WHEN Xuatnhap.Loaiphieu="X" 
                     AND SQLQuery1.FieldByName("Ngay").asString <= StrToDate(Edit1.Text) 
                THEN Xuatnhap.Soluong   
              ELSE 0  
           END) AS Tongxuat
          ,SUM(CASE 
                WHEN Xuatnhap.Loaiphieu="N" 
                     AND SQLQuery1.FieldByName("Ngay").asString <= StrToDate(Edit1.Text) 
                THEN Xuatnhap.Soluong 
               ELSE 0 
               END) - SUM(CASE 
                            WHEN Xuatnhap.Loaiphieu="X" 
                                 AND SQLQuery1.FieldByName("Ngay").asString <= StrToDate(Edit1.Text) 
                            THEN Xuatnhap.Soluong 
                            ELSE 0  
                          END) AS Tongton 
         FROM Mathang INNER JOIN Xuatnhap 
                    ON Mathang.Mahang=Xuatnhap.Mahang 
                   GROUP BY  Mathang.Stt,Mathang.Mahang, Mathang.Tenhang';
`

1 Ответ

1 голос
/ 02 февраля 2020

Есть несколько проблем с вашим q;

Во-первых, хотя код, который вы изначально разместили как синтаксически правильный, кто-то отредактировал его, я предполагаю, чтобы улучшить его разборчивость, чтобы RHS задания был в нескольких строках, и это сделало его синтаксически неправильным. Причина неверна в том, что в Pascal открывающая кавычка ' строкового выражения должна появляться на той же строке, что и закрывающая кавычка: пример ниже показывает, как обойти это.

Во-вторых, Я предполагаю, что вы намереваетесь присвоить значение вашей переменной str SQL свойству SQL вашего SQLQuery1, но если это так, есть несколько проблем с ним.

Это помогло бы, если бы вы попытались итеративно комментируя все, кроме одного из предложений SUM, и все, кроме одного из выражений в нем, чтобы точно определить, где происходит ошибка.

Однако, скорее всего, ошибка содержится в выражении

SQLQuery1.FieldByName ("Ngay"). AsString <= StrToDate (Edit1.Text) </p>

, который встречается в 4 местах. Причина в том, что создаваемая вами строка SQL передается движку Sqlite (содержится в файле Sqlite3.Dll) для выполнения, и она не имеет доступа к тому, что содержится в свойствах компонентов вашего приложения. Таким образом, недопустимо, чтобы SQL содержал ссылки на содержимое полей компонента SQLQuery1, содержимое текстового поля Edit1 и функцию Lazarus StrToDate. Вам нужно будет заменить их значениями, действительными в выражении SQL, такими как значения в столбцах соединенных таблиц, константы или значения параметров в запросе.

Следующая проблема заключается в том, что даже если вышеуказанные проблемы будут исправлены, ваш код будет уязвим для SQL injection - см. https://en.wikipedia.org/wiki/SQL_injection. Чтобы избежать этого, вместо того, чтобы включать содержимое Edit1.Text в SQL, отправляемый на сервер, вы должны параметризовать SQL с параметром date и использовать содержимое Edit1.Text для предоставления значения параметр.

Итак, было бы лучше написать ваше назначение str SQL примерно так (я буду использовать очень упрощенную версию)

strSQL :=
  'Select ' +
  '  * ' +
  'from ' +
  '  MyTable ' +
  'where ' +
    'Date <= :Date ';  //  :Date is the parameter value for the Date column of MyTable

Затем вы можете использовать это SQL для выполнения запроса

if SqlQuery1.Active then
  SqlQuery1.Close;
SqlQuery1.Params.ParamByName('Date').Value := StrToDate(Edit1.Text);

SqlQuery1.Prepare;
SqlQuery1.Open;
...