Метки:
  1. kickbeat

    kickbeat Новичок

    Сообщения:
    8
    Ваш город:
    Saratov, Россия
    Address:
    Saratov, Russia
    Country:
    Location on Map:
    Доброго времени суток!

    Делаю запрос к БД MS SQL через ajax.
    Код:
    function getActiveDevice(tec_id, device_id) {
          $.ajax({
              url: "php/sqlQuery.php",
              type: "GET",
              dataType: "json",
              data: {
                tec_id:tec_id,
                device_id:device_id
              },
              success:function(result){
                  console.log("Success: ", result);
                },
              error:function(jqXHR, textStatus, errorThrown) {
                console.log('textStatus: '+ textStatus);
                console.log('error: ' + errorThrown);
              }
          });
    }

    в sqlQuery.php делается выборка и формируется массив
    PHP:
    <?php
     
    $id_tec 
    $_GET['tec_id'];
    $id_device $_GET['device_id'];
     
    // подключение к БД
    include_once '../php/DBconnect.php';
     
    if (
    $id_tec == 0) {
      echo 
    json_encode(array("c" => "all"));
      exit();
    } else {
        
    // выборка из объединенных таблиц gftec и Device по полю gftec.tabl=device.id
     
    // !!вопрос в этом запросе!!
        
    $db_query "SELECT gftec.[Id]
                            ,gftec.[ID_TEC]
                            ,gftec.[dattime]
                            ,gftec.[p]
                            ,gftec.[t]
                            ,gftec.[q]
                            ,gftec.[tabl]
                              ,Device.[ID] as 'id_dev'
                              ,Device.[Name]
                              ,Device.[OrderNum]
                              ,Device.[IdDataType]
                  FROM (
                    SELECT * FROM gftec WHERE [ID_TEC]="
    .$id_tec.") AS gftec JOIN (
                    SELECT * FROM Device WHERE [Id_tec]="
    .$id_tec.") AS device ON gftec.[tabl]=device.[ID]
                    WHERE gftec.[Id] IN (select max(Id) FROM gftec WHERE gftec.[ID_TEC]="
    .$id_tec." GROUP BY gftec.[tabl])
                    ORDER BY device.[OrderNum]"
    ;
    }
    // формирование массива значений
     
        
    $odbc_result odbc_exec($db_connect,$db_query);
        
    $device_cont odbc_num_rows($odbc_result);
     
        if (
    $odbc_result) {
            for (
    $i=0$i <$device_cont $i++) {
              
    $res_d_name[$i] = odbc_result($odbc_result,"Name");
              
    $res_p[$i] = odbc_result($odbc_result,"p");
              
    $res_t[$i] = odbc_result($odbc_result,"t");
              
    $res_q[$i] = odbc_result($odbc_result,"q");
              
    $res_dattime[$i] = date("d:m:Y h:i:s"strtoTime(odbc_result($odbc_result,"dattime")));
              
    odbc_fetch_row($odbc_result);
          }
           echo 
    json_encode(array('c' => $device_cont'd_name' => $res_d_name'p' => $res_p't' => $res_t'q' => $res_q'dattime' => $res_dattime));
          } else { 
           echo 
    "\n - table isn't readed"; }
    ?>
    в средствах разработчика браузера результат всего этого:
    - в логах "error: SyntaxError: Синтаксическая ошибка"
    - в network есть запись о запросе, но получено 0 B

    Проблема в том, что данный SELECT был отлажен в MS SQL Server Manadement Studio. И там он отлично работает. Но при копировании запроса в php, результатом становится "синтаксическая ошибка" (результат не меняется, если вместо переменных вставляю явные значения). Как я понимаю, для php чего-то в этом запросе не хватает. Синтаксис php проверялся неоднократно - вместо переменных вставлял обычные значения, все двойные/одинарные кавычки, скобки, точки с запятой - все, вроде бы, на месте, но...

    p.s. Не знаю поможет ли эта история, но вот работающий запрос (собственно его и переделываю):
    PHP:
        $db_query "SELECT [Id]
                         ,[ID_TEC]
                         ,[dattime]
                         ,[p]
                         ,[t]
                         ,[q]
                         ,[tabl]
                      FROM [GF].[dbo].[gftec]
                      where [ID_tec]="
    .$id_tec." and [Id] in (select max(id) from [GF].[dbo].[gftec]
                                                                      where [ID_TEC]="
    .$id_tec."
                                                                      group by [tabl])"
    ;
    так вот изначально он был без where в 10-й (предпоследней) строке и все в той же менеджмент студии работал отлично, но при вставке в php работать отказывался. Я уже не помню, как додумался до добавления этой 10-й строки, однако смысла ее добавления ни тогда, ни сейчас так и не понял и воспринимал, как бубен. Но вот второй запрос со схожими симптомами вызывает подозрения...
    [​IMG] [​IMG]
    0
     
  2. c0dex

    c0dex web.dev 2002-... Команда форума Партнер клуба

    Сообщения:
    7.700
    Ваш город:
    Moscow, Russia
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Ну так в чем проблема?

    Вызови свой php/sqlQuery.php?tec_id=123&device_id=456 прямо в браузере и занимайся отладкой спокойно.

    http://phpfaq.ru/debug
     
    kickbeat нравится это.
  3. AnrDaemon

    AnrDaemon Продвинутый новичок

    Сообщения:
    4.609
    Ваш город:
    Moscow, Russia
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Проблема, очевидно, в
    SELECT * FROM gftec WHERE [ID_TEC]=".$id_tec
    SELECT * FROM Device WHERE [Id_tec]=".$id_tec
     
  4. kickbeat

    kickbeat Новичок

    Сообщения:
    8
    Ваш город:
    Saratov, Россия
    Address:
    Saratov, Russia
    Country:
    Location on Map:
    эм... ну там все то же самое, что и через обычную консоль. Своей html разметки этот .php не имеет, чтобы визуально контролировать. Остается консоль. То, что переменные от запроса пришли - это видно, то, что ответ 0 - тоже, но, если запрос не отработал, то это естественно. Массив не сформирован, возвращать нечего. А сам текст запроса я не вижу, в каком виде он попадает на обработку.

    Честно говоря, для меня не очевидно. Что не так с этими кусками селектов?
     
  5. Фанат

    Фанат oncle terrible Команда форума

    Сообщения:
    39.946
    Ваш город:
    Moscow, Russia
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    В том что ты не копируешь рабочий запрос, а переписываешь его от руки

    И странно что никто до сих пор про SQL injection не написал
     
  6. kickbeat

    kickbeat Новичок

    Сообщения:
    8
    Ваш город:
    Saratov, Россия
    Address:
    Saratov, Russia
    Country:
    Location on Map:
    в стартовом сообщении я писал
    после чего оно именно приходило в тот самый вид с конкретными цифрами. Но переменные передаются правильно. Текст самого последнего запроса (который работающий) тоже через те же самые переменные - все работает
     
  7. Breeze

    Breeze goshogun Команда форума Партнер клуба

    Сообщения:
    1.700
    Ваш город:
    Moscow
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    т.е. сделать print $db_query; невозможно ни при каких обстоятельствах
     
    kickbeat нравится это.
  8. AnrDaemon

    AnrDaemon Продвинутый новичок

    Сообщения:
    4.609
    Ваш город:
    Moscow, Russia
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    "Не так" готовая SQL injection.
     
  9. antson

    antson на форуме с 2005 года Партнер клуба

    Сообщения:
    1.291
    Ваш город:
    Россия, Липецк
    Address:
    Lipetsk, Russia
    Country:
    Location on Map:
    @kickbeat, я надеюсь этот скрипт крутиться под IIS в интранете вашей организации ?
     
  10. kickbeat

    kickbeat Новичок

    Сообщения:
    8
    Ваш город:
    Saratov, Россия
    Address:
    Saratov, Russia
    Country:
    Location on Map:
    эм... не знаю. Это первое мое знакомство и с пхп и вообще с вэб-программированием. Поэтому пробелов у меня еще ой как много. И в основах их полно в том числе. Спасибо, попробую.
    Да, это для внутреннего использования строго ограниченного круга лиц. GET специально использовал, чтобы видеть строку адреса вместе со значениями, принимаемыми переменными
     
  11. Фанат

    Фанат oncle terrible Команда форума

    Сообщения:
    39.946
    Ваш город:
    Moscow, Russia
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    А теперь попробуй объяснить, при чем здесь синтаксис РНР
     
  12. kickbeat

    kickbeat Новичок

    Сообщения:
    8
    Ваш город:
    Saratov, Россия
    Address:
    Saratov, Russia
    Country:
    Location on Map:
    при том, что от руки я только конкретные числа заменил на переменные в скопированном рабочем запросе. Ну я так понял, что имелось в виду это и что именно в синтаксисе встраивания переменных в запрос накосячил.

    хм. спасибо тебе, добрый человек, который про print напомнил. В общем понатыкал я этого принта везде, где только можно, начиная от входных данных и заканчивая создаваемым массивом
    PHP:
            $arr = array('c' => $device_cont'd_name' => $res_d_name'p' => $res_p't' => $res_t'q' => $res_q'dattime' => $res_dattime);
            
    print_r($arr);
    дальше уже только возврат массива... так что прошу прощения, с sql все нормально. Похоже, нужно искать ошибку в другом месте

    Нашел...
    проблема в выводе массива
    PHP:
    echo json_encode(array('c' => $device_count'd_name' => $res_d_name'p' => $res_p't' => $res_t'q' => $res_q'dattime' => $res_dattime));
    как только я убираю из массива d_name, ошибка сразу пропадает...
    Но за этим как раз я и переделывал запрос. Что такого особенного в этом d_name? Обычные названия...
     
    Последнее редактирование: 4 окт 2018
  13. ksnk

    ksnk прохожий

    Сообщения:
    1.060
    Address:
    Sankt-Peterburg, Russia
    Country:
    Location on Map:
    json_last_error ?
    Текст в utf-8 ?
     
  14. kickbeat

    kickbeat Новичок

    Сообщения:
    8
    Ваш город:
    Saratov, Россия
    Address:
    Saratov, Russia
    Country:
    Location on Map:
    либо все ок, либо я не так пользуюсь проверками...

    еще раз закину свои коды, т.к. были многочисленные эксперименты
    JS - Изменения от первоначального: убрал dataType, добавил cache: "false", в приемник добавил проверку на валидность
    Код:
          $.ajax({
              url: "php/sqlQuery.php",
              type: "GET",
             // dataType: "json",
              async: "false",
              cache: "false",
              data: {
                tec_id:tec_id,
                device_id:device_id
              },
              success:function(result){
                try {
                  var output = JSON.parse(result);
                  console.log(output);
                } catch (e) {
                  console.log("Output is not valid JSON: " + result);
                }
              },
              error:function(jqXHR, textStatus, errorThrown) {
                console.log('textStatus: '+ textStatus);
                console.log('error: ' + errorThrown);
              }
    
          });
    
    в php добавил проверку на валидность (нашел в инете). Т.е. ЛИБО возвращает массив, ЛИБО пробегает по ошибкам... ну или так должно быть...
    PHP:
    <?php

    $id_tec 
    $_GET['tec_id'];
    $id_device $_GET['device_id'];

    // подключение к SQL
    include_once '../php/DBconnect.php';

    if (
    $id_tec == 0) {            // если выбран весь филиал (id_tec=0).
      
    echo json_encode(array("c" => "all station"));
      exit();
    } else if (
    $id_device == 99999)  // если выбран пункт "общие" (id_device=99999). Выборка по всем последним значениям.
      
    {
        
    // выборка из объединенных таблиц gftec и Device по полю gftec.tabl=device.id
        
    $db_query "SELECT gftec.[Id]
                            ,gftec.[ID_TEC]
                            ,gftec.[dattime]
                            ,gftec.[p]
                            ,gftec.[t]
                            ,gftec.[q]
                            ,gftec.[tabl]
                              ,Device.[ID] as 'id_dev'
                              ,Device.[Name]
                              ,Device.[OrderNum]
                              ,Device.[IdDataType]
                    FROM (
                      SELECT * FROM gftec WHERE [ID_TEC]="
    .$id_tec.") AS gftec JOIN (
                      SELECT * FROM Device WHERE [Id_tec]="
    .$id_tec.") AS device ON gftec.[tabl]=device.[ID]
                  WHERE gftec.[Id] IN (select max(Id) FROM gftec WHERE gftec.[ID_TEC]="
    .$id_tec." GROUP BY gftec.[tabl])
                    ORDER BY device.[OrderNum]"
    ;
      } else {
        
    // если выбран конкретный прибор
        
    $db_query "SELECT top (1) [Id]
                         ,[ID_TEC]
                         ,[dattime]
                         ,[p]
                         ,[t]
                         ,[q]
                         ,[tabl]
                   FROM [GF].[dbo].[gftec]
                   WHERE ID_TEC="
    .$id_tec." and tabl=".$id_device." ORDER BY [Id] desc";
    }

    // формирование массива значений запроса
        
    $odbc_result odbc_exec($db_connect,$db_query);
        
    $device_count odbc_num_rows($odbc_result);

        if (
    $odbc_result)
        {
            for (
    $i=0$i <$device_count $i++) {
              
    $res_dn[$i] = odbc_result($odbc_result,"Name");
              
    $res_p[$i] = odbc_result($odbc_result,"p");
              
    $res_t[$i] = odbc_result($odbc_result,"t");
              
    $res_q[$i] = odbc_result($odbc_result,"q");
              
    $res_dattime[$i] = date("d:m:Y h:i:s"strtoTime(odbc_result($odbc_result,"dattime")));
              
    odbc_fetch_row($odbc_result);
          }

            
    // массив
            
    $arr = array("c" => $device_cont"dname" => $res_dn"p" => $res_p"t" => $res_t"q" => $res_q"dattime" => $res_dattime);
       
          
    //  print_r($arr);

         // проверка на валидность массива
          
    if (is_object(json_decode($arr))) {
                echo 
    json_decode($arr);
                exit();
              } else {
                
    // switch and check possible JSON errors
                
    switch (json_last_error()) {
                    case 
    JSON_ERROR_NONE:
                        
    $error 'JSON is valid'// No error has occurred
                        
    break;
                    case 
    JSON_ERROR_DEPTH:
                        
    $error 'The maximum stack depth has been exceeded.';
                        break;
                    case 
    JSON_ERROR_STATE_MISMATCH:
                        
    $error 'Invalid or malformed JSON.';
                        break;
                    case 
    JSON_ERROR_CTRL_CHAR:
                        
    $error 'Control character error, possibly incorrectly encoded.';
                        break;
                    case 
    JSON_ERROR_SYNTAX:
                        
    $error 'Syntax error, malformed JSON.';
                        break;
                    
    // PHP >= 5.3.3
                    
    case JSON_ERROR_UTF8:
                        
    $error 'Malformed UTF-8 characters, possibly incorrectly encoded.';
                        break;
                    
    // PHP >= 5.5.0
                    
    case JSON_ERROR_RECURSION:
                        
    $error 'One or more recursive references in the value to be encoded.';
                        break;
                    
    // PHP >= 5.5.0
                    
    case JSON_ERROR_INF_OR_NAN:
                        
    $error 'One or more NAN or INF values in the value to be encoded.';
                        break;
                    case 
    JSON_ERROR_UNSUPPORTED_TYPE:
                        
    $error 'A value of a type that cannot be encoded was given.';
                        break;
                    default:
                        
    $error 'Unknown JSON error occured.';
                        break;
                }

                if (
    $error !== 'JSON is valid') {
                    
    // throw the Exception or exit // or whatever :)
                    
    print "wrong json: ".$error;
                } else {
                  
    // everything is OK
                    
    print "valid json: ".$error;
                }
              }

            
    //echo json_encode( Array ( 'c' => 6, 'd_name' => Array ( 'Прямая Т.С', 'Обратная Т.С', 'Подпитка Т.С', 'Пром.вода', 'Пром. ввод газа', 'Гор.ввод газа' ), 'p' => Array ( 8.0184870000000004, 1.7380519999999999, 1.8435520000000001, -0.18861900000000001, 4.2474769999999999, 4.451854 ), 't' => Array ( 81.0, 52.0, 85.0, 16.0, -1.0, -3.0 ), 'q' => Array ( 1869.670044, 1887.8157960000001, 0.0, 0.0, 10809.722656, 0.0 ), 'dattime' => Array ( '09:01:2017 11:15:00', '09:01:2017 11:16:00', '09:01:2017 11:16:00', '09:01:2017 11:16:00', '09:01:2017 11:15:00', '09:01:2017 11:16:00' ) ) );
            //var_dump(array('c' => $device_count, 'd_name' => $res_dn, 'p' => $res_p, 't' => $res_t, 'q' => $res_q, 'dattime' => $res_dattime));
            //echo json_encode(array('c' => $device_count, 'd_name' => $res_dn, 'p' => $res_p, 't' => $res_t, 'q' => $res_q, 'dattime' => $res_dattime));

          
    }
        else
           {          echo 
    "\n - sqlQuery.php - The table isn't readed";      }
    ?>

    итоги:
    в самом sqlQuery.php результат выводит
    (!!! т.е. пишет, что все ок, но таки провалившись в ошибки...)
    в целом в консоли:
    - при убранном dataType:
    (!!! т.е. php-шная проверка считает, что все ок (опять же см выше про этот "ок", JS - наоборот... вот такой вот поворот...)
    - вернул dataType:
    где 1 строка - для случая id_tec==0
    2 и 3 - для id_device==99999
    и 2 последние - 3 случай для выборки в sqlQuery
    (1 и 2 ответ просто для сведений - внимания особо не обращаем, т.к. это временные затычки)
     
    Последнее редактирование: 9 окт 2018
  15. ksnk

    ksnk прохожий

    Сообщения:
    1.060
    Address:
    Sankt-Peterburg, Russia
    Country:
    Location on Map:
    Очевидно, что строка `valid json: JSON is valid` не является валидным json...
    Это тоже невалидный json/ Вероятно, кто-то его уже один раз отjson'ил и уже получил объект
     
    Последнее редактирование: 9 окт 2018
  16. kickbeat

    kickbeat Новичок

    Сообщения:
    8
    Ваш город:
    Saratov, Россия
    Address:
    Saratov, Russia
    Country:
    Location on Map:
    согласен, первое и не может пройти проверку, НО почему оно вообще в обработку попадает?
    PHP:
    if (is_object(json_decode($arr))) {
                echo 
    json_decode($arr);
                exit();
              } else {
                
    // switch and check possible JSON errors
                
    switch (json_last_error()) {
                    case 
    JSON_ERROR_NONE:
                        
    $error 'JSON is valid'// No error has occurred
                        
    break;
    как трактовать такое поведение в этом куске? Т.е. это то ли не объект, то ли не деJSONится, но при этом по last_error'у все отлично - error'ов нет...

    и главный же вопрос так и остается - что такого невалидного в возвращаемом массиве (а если совсем точно, то во входящем в него массиве "dname")?
    Если подумать, то единственное отличие, которое я вижу, это русские названия... var_dump показал, что все переменные в массиве, кроме первого счетчика (он типа INT) строковые. Т.е. с типами данных, вроде бы, порядок. Соответственно, единственное, что приходит на ум - кодировка. Но проверку то я воткнул. Там есть возврат ошибки кодировки, но оно не отрабатывает. т.е. все ок получается опять?
    По кускам - все ок, а как в целом - все плохо..
     
  17. kickbeat

    kickbeat Новичок

    Сообщения:
    8
    Ваш город:
    Saratov, Россия
    Address:
    Saratov, Russia
    Country:
    Location on Map:
    Действительно в кодировке причина:

    PHP:
    $res_d_name[$i] = iconv('windows-1251''utf-8'odbc_result($odbc_result,"Name"));
    всем спасибо. Проблема решена