Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

29 Апрель 2017, 10:32 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Доступно и просто о работе в офисных пакетах
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1 2 »   Вниз
  Печать  
Автор Тема: Запрос к базе данных из StarBasic возвращает неожиданный результат  (Прочитано 1034 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ost
Пользователь
**
Offline Offline

Сообщений: 54


« Стартовое сообщение: 8 Февраль 2017, 18:12 »

Доброго
Объясните, пожалуйста, причину странного результата команды SELECT в случае если запрашивается выборка по несуществующему полю.

Странность заключается в том, что при выполнении
Код:
...
ResultSet = Statement.executeQuery("SELECT ""Absent"" FROM ""B""")
в случае отсутствия в таблице "B" поля "Absent" вместо ожидаемой ошибки а-ля "no such column: Absent"
получаю таблицу-выборку с числом записей равным числу записей в таблице "B" и одной колонкой-полем. При этом значение полей всех записей равно "Absent".
О_о


« Последнее редактирование: 8 Февраль 2017, 18:14 от ost » Записан
mikekaganski
Старожил
****
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 406


« Ответ #1: 8 Февраль 2017, 18:29 »

Ну, специалистов по абсенту я здесь не помню, только по коньяку... Улыбка

А если серьёзно - Вы же берёте строку в кавычки - это уже не название поля, а строковое выражение. Ну, могло быть так (если числовое поле Z есть):

SELECT 1 + Z FROM "B" - выдаст число записей, соответствующее размеру таблицы - а числа не как в ячейке, логично?
SELECT 1 FROM "B" - выдаст число записей, соответствующее размеру таблицы - а числа все 1;
SELECT "Absent" FROM "B" - аналогично
Записан

С уважением,
Михаил Каганский
economist
Ветеран
*****
Offline Offline

Сообщений: 502


« Ответ #2: 8 Февраль 2017, 22:22 »

Кто-ж так абсент выбирает? Нужно без кавычек :-)

Вот, кстати, как можно писать код, если СУБД к Base выбрана не HSQL, а нормальная, тот же SQLite - то про неприязнь к кириллице и кавычки можно забыть:    

Код:
ResultSet = Statement.executeQuery("SELECT ФИО, АДРЕС, ОКЛАД, * FROM СОТРУДНИКИ WHERE ОКЛАД>100000 AND 2 LIKE '%Москва%'")

Ну красиво же!
« Последнее редактирование: 8 Февраль 2017, 22:25 от economist » Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
ost
Пользователь
**
Offline Offline

Сообщений: 54


« Ответ #3: 9 Февраль 2017, 10:42 »

Спасибо за ответы. Продолжим с абсентом, не злоупотребляя. =)
Вот, кстати, как можно писать код, если СУБД к Base выбрана не HSQL, а нормальная, тот же SQLite
Да, база используется SQLite. Тем не менее запрос вида:
Код:
ResultSet = Statement.executeQuery("SELECT Absent FROM B")
при условии, что поле "Absent" отсутствует в таблице "B" результат не изменяет. На выходе имеем точно такую же таблицу-выборку:
1. Число строк=числу записей в таблице базы данных.
2. Количество полей=1.
3. Значение всех полей="Absent".

Где ошибаюсь не пойму. Может, ошибка в сопутствующем коде?
Прилагаю файлик с макросом. Ткните, пожалуйста, в косячное место.

* QSLite_LO_test.ods (15.25 Кб - загружено 13 раз.)
Записан
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 055


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #4: 9 Февраль 2017, 11:18 »

Где ошибаюсь не пойму. Может, ошибка в сопутствующем коде?
Прилагаю файлик с макросом. Ткните, пожалуйста, в косячное место.
Код вроде без ошибок. У меня нет SQLite, а в HSQL нормально, ругается если нет таблицы или поля. Нужно смотреть документацию SQLite, возможно это её особенность или глюк.

Какой результат вы хотите получить если запрашиваете несуществующие данные Непонимающий
Записан

economist
Ветеран
*****
Offline Offline

Сообщений: 502


« Ответ #5: 9 Февраль 2017, 11:36 »

Есть в Base одна пакостная вещь - свой парсер SQL-выражений, порождающий недоумение и злобу.
В GUI BASE - это та самая таинственная кнопка в Query Designe, на которой написано три буквы: SQL. Ненажатая - она коверкает запрос так, что ODBC-драйверы запрос не понимают, или работают не так как надо. Это параметр EscapeProcessing = False  

Не проверял, но думаю нужно так:
Код:
Statement = bd.createStatement()
Statement.EscapeProcessing = False 'вот оно чё, Михалыч!

В BASIC-коде лучше все данные из БД закачивать в динамический объект типа RecordSet, который по сути предоставляет самый быстрый и бесконфликтный способ подвыборки, изменения и удаления данных в базе.
Сейчас могу лишь копипастнуть свой код:

Код:
RowSet = createUnoService("com.sun.star.sdb.RowSet") ' создаем
RowSet.DataSourceName = "YourDataBase" ' указываем зарегистрированную базу данных, без *.odb!
RowSet.CommandType = com.sun.star.sdb.CommandType.COMMAND ' вызываем команду
RowSet.EscapeProcessing=FALSE
SQLSTR="SELECT * FROM СОТР"
RowSet.Command = SQLSTR 'задаем команду для набора строк
'On Error Goto ErrSQL
RowSet.execute() ' выполняем
rowSet.Last 'мотнули курсор к концу, чтобы узнать сколько строк
RowEND=(rowSet.RowCount()-1)
rowSet.First ' вернулись к первой записи. Теперь можно циклом перебрать  
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
economist
Ветеран
*****
Offline Offline

Сообщений: 502


« Ответ #6: 9 Февраль 2017, 11:42 »

Если в SQLite-базе есть, как у меня, кириллические таблицы и поля - нужно еще настроить ODBC/unixODBC-драйвер. Кириллица, кстати, работает без глюков. С её помощью я научил писать запросы пару десятков человек, на английском процесс не шел даже под угрозой увольнения (это к вопросу о поддержке кириллицы везде, где можно и почему нельзя в ней отказывать простым людям). 
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
ost
Пользователь
**
Offline Offline

Сообщений: 54


« Ответ #7: 9 Февраль 2017, 11:46 »

Какой результат вы хотите получить
Ошибку выполнения или любой другой результат, который можно было бы отловить в макросе и соотнести с ошибкой.
Записан
economist
Ветеран
*****
Offline Offline

Сообщений: 502


« Ответ #8: 9 Февраль 2017, 11:48 »

Сейчас еще раз перечитал ветку (не спал ночь из-за урагана, сорри) и понял что

ResultSet = Statement.executeQuery("SELECT Absent FROM B")


- ведет себя так потому что Absent воспринимается чем-то как литерал. Это чем-то может быть как движок Base, так и конкретный ODBC-драйвер. Голая SQLite так себя не ведет.

Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
economist
Ветеран
*****
Offline Offline

Сообщений: 502


« Ответ #9: 9 Февраль 2017, 11:50 »

Из настроек ODBC-драйвера для Windows - нужно включить лишь OEMCP Translation.
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
economist
Ветеран
*****
Offline Offline

Сообщений: 502


« Ответ #10: 9 Февраль 2017, 11:57 »

Для будущих поколений и в защиту великого и могучего русского языка в запросах: "русско"-фобия играет злую шутку с её апологетами. Абсент хоть и не входит в SQL reserved words, но может войти в любую секунду. Поэтому собирая запрос по кускам, проверяйте - не вошло ли имя таблицы/поля/псевдонима в этот список:

Код:

reservedSQL = Array("ACCESSIBLE", "ADD", "ALL", "ALTER", "ANALYZE", "AND", "AS", "ASC", "ASENSITIVE", "BEFORE", _
"BETWEEN", "BIGINT", "BINARY", "BLOB", "BOTH", "BY", "CALL", "CASCADE", "CASE", "CHANGE", "CHAR", "CHARACTER", "CHECK", "COLLATE", _
"COLUMN", "CONDITION", "CONSTRAINT", "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT_DATE", "CURRENT_TIME", _
"CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DATABASE", "DATABASES", "DAY_HOUR", "DAY_MICROSECOND", "DAY_MINUTE", _
"DAY_SECOND", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DELAYED", "DELETE", "DESC", "DESCRIBE", "DETERMINISTIC", "DISTINCT", _
"DISTINCTROW", "DIV", "DOUBLE", "DROP", "DUAL", "EACH", "ELSE", "ELSEIF", "ENCLOSED", "ESCAPED", "EXISTS", "EXIT", _
"EXPLAIN", "FALSE", "FETCH", "FLOAT", "FLOAT4", "FLOAT8", "FOR", "FORCE", "FOREIGN", "FROM", "FULLTEXT", "GET", "GRANT", _
"GROUP", "HAVING", "HIGH_PRIORITY", "HOUR_MICROSECOND", "HOUR_MINUTE", "HOUR_SECOND", "IF", "IGNORE", "IN", "INDEX", "INFILE", _
"INNER", "INOUT", "INSENSITIVE", "INSERT", "INT", "INT1", "INT2", "INT3", "INT4", "INT8", "INTEGER", "INTERVAL", "INTO", _
"IO_AFTER_GTIDS", "IO_BEFORE_GTIDS", "IS", "ITERATE", "JOIN", "KEY", "KEYS", "KILL", "LEADING", "LEAVE", "LEFT", "LIKE", _
"LIMIT", "LINEAR", "LINES", "LOAD", "LOCALTIME", "LOCALTIMESTAMP", "LOCK", "LONG", "LONGBLOB", "LONGTEXT", "LOOP", "LOW_PRIORITY", _
"MASTER_BIND", "MASTER_SSL_VERIFY_SERVER_CERT", "MATCH", "MAXVALUE", "MEDIUMBLOB", "MEDIUMINT", "MEDIUMTEXT", "MIDDLEINT", _
"MINUTE_MICROSECOND", "MINUTE_SECOND", "MOD", "MODIFIES", "NATURAL", "NONBLOCKING", "NOT", "NO_WRITE_TO_BINLOG", "NULL", _
"NUMERIC", "ON", "OPTIMIZE", "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT", "OUTER", "OUTFILE", "PARTITION", "PRECISION", _
"PRIMARY", "PROCEDURE", "PURGE", "RANGE", "READ", "READS", "READ_WRITE", "REAL", "REFERENCES", "REGEXP", "RELEASE", "RENAME", "REPEAT", _
"REPLACE", "REQUIRE", "RESIGNAL", "RESTRICT", "RETURN", "REVOKE", "RIGHT", "RLIKE", "SCHEMA", "SCHEMAS", "SECOND_MICROSECOND", _
"SELECT", "SENSITIVE", "SEPARATOR", "SET", "SHOW", "SIGNAL", "SMALLINT", "SPATIAL", "SPECIFIC", "SQL", "SQLEXCEPTION", "SQLSTATE", _
"SQLWARNING", "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", "SSL", "STARTING", "STRAIGHT_JOIN", "TABLE", "TERMINATED", _
"THEN", "TINYBLOB", "TINYINT", "TINYTEXT", "TO", "TRAILING", "TRIGGER", "TRUE", "UNDO", "UNION", "UNIQUE", "UNLOCK", "UNSIGNED", "UPDATE", _
"USAGE", "USE", "USING", "UTC_DATE", "UTC_TIME", "UTC_TIMESTAMP", "Values", "VARBINARY", "VARCHAR", "VARCHARACTER", "VARYING", "WHEN", _
"WHERE", "WHILE", "WITH", "WRITE", "XOR", "YEAR_MONTH", "ZEROFILL")
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
economist
Ветеран
*****
Offline Offline

Сообщений: 502


« Ответ #11: 9 Февраль 2017, 12:04 »

Ну а по сабжу - Statement.EscapeProcessing = False  - не помог. Похоже, это сама SQLite так себя ведет.
Так что отлавливайте ошибку программно. То есть если ФИО отсутствующих равно нескольким Absent - то они его приняли дома, и незримо присутствуют на работе/учебе. Не вижу здесь большой беды.

SQLite вообще довольно либеральна к неточностям, Абсента ей не жалко. У Пабло Пикассо есть соответствующая КДПВ: "Любительница Абсента".
« Последнее редактирование: 9 Февраль 2017, 12:11 от economist » Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
ost
Пользователь
**
Offline Offline

Сообщений: 54


« Ответ #12: 9 Февраль 2017, 12:35 »

Ну а по сабжу - Statement.EscapeProcessing = False  - не помог
Мне помог. =) ODBC драйвер использовал этот: http://www.ch-werner.de/sqliteodbc/
Спасибо за обстоятельные ответы с примерами и дельные советы. Буду разбираться.
Записан
economist
Ветеран
*****
Offline Offline

Сообщений: 502


« Ответ #13: 9 Февраль 2017, 13:20 »

ost - скажете еще вашу версию OpenOffice|LibreOffice и Windows, вдруг кто еще столкнется с проблемой?!
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
ost
Пользователь
**
Offline Offline

Сообщений: 54


« Ответ #14: 9 Февраль 2017, 14:58 »

LibreOffice 5.2.5.1 (x64)
Win 7 (x64)
Записан
Страниц: 1 2 »   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!