Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Динамический курсор / 25 сообщений из 27, страница 1 из 2
09.09.2004, 21:12
    #32688530
leokolus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Всем привет, уважаемые мастера помогите "чайнику". бьюсь над кодом уже три дня и ничего не получается.

Задача: есть база данных, надо нажав кнопку (cb_3) проверить есть ли в ней некоторая величина и получить её значение в строковую переменную (ls_find). При этом все значения запроса SELECT являются переменными:
Ниже я привожу код который я написал, он компилируется но строковая переменная (ls_find) остаётся пустой.

Код для кнопки cb_3

String ls_prcolumn, ls_ptable, ls_dept, ls_Item, ls_find
String SQL_Exp

ls_prcolumn = String(sle_prcolumn.text) // колонка
ls_ptable = String(sle_prtable.text) // таблица
ls_dept = String(sle_dept.text) + "000001" // условие WHERE
ls_Item = lb_notfound.SelectedItem() // условие для WHERE берётся из ListBox

DECLARE my_cursor DYNAMIC CURSOR FOR SQLSA ;
SQL_Exp = "select " + String(ls_prcolumn) + " from amos." + String(ls_ptable) + " where " + String(ls_prcolumn) + " = ? and deptid = " + String(ls_dept) + ";"
PREPARE SQLSA FROM :SQL_Exp ;
OPEN DYNAMIC my_cursor USING :ls_Item;
FETCH my_cursor INTO :ls_find;

if oracle_trans.sqlcode = 0 then // если запрос выполняется то полученное
// значение выводится в (sle_find)
sle_find.text = ls_find

CLOSE my_cursor ;

if ls_find = ls_Item then // если выполняется это условие то появляется
// сообщение что величина есть в базе данных и наоборот

MessageBox( "Value found", String(ls_prcolumn) + " = " + String(ls_Item) + " found!", Information!, Ok!, 1)

else

MessageBox( "Value not found", String(ls_prcolumn) + " = " + String(ls_Item) + " not found!", Information!, Ok!, 1)

end if
...
Рейтинг: 0 / 0
10.09.2004, 08:47
    #32688747
Ikar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
1. курсор там совершенно ни к чему.

2. если в дебаггере, посе прохождения строки
Код: plaintext
1.
2.
SQL_Exp = "select " + String(ls_prcolumn) + " from amos." + &
String(ls_ptable) + " where " + String(ls_prcolumn) + &
" = ? and deptid = " + String(ls_dept) + ";" 
взять значение из переменной SQL_Exp , то поучаете ли Вы там "честный" селект? Сколько рядов возвращает этот селект?

3. я не знаю оракл, но тем не менее кусочек выражения " = ? and " меня смущает. Или это просто опечатка?

4. если п.2 дает полный и честный сеект, то сдеайте на его основе datastore и будет Вам счастье... ;-)

Создание datastore
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
String sql_select
sql_select = 'select a from table where b = c'
datastore dt_stor
dt_stor = create datastore
dt_stor.SetTransObject( transaction_object)
dt_stor.SetSqlSelect(sql_select)
dt_stor.Retrieve()
if dt_stor.RowCount() <=  0  then
    Messagebox('error', 'value not found')
    destroy dt_stor
end if
if dt_stor.RowCount() >  1  then
    Messagebox('error', 'value found > 1')
    destroy dt_stor
end if
string znachenie
znachenie = dt_stor.GetItemStrung( 1 ,  1 )
destroy dt_stor

---
С уважением, IKAR

ikarhomecenter@narod.ru
IkarHomeCenter
...
Рейтинг: 0 / 0
10.09.2004, 10:47
    #32689033
Геннадич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Так ничего не получится. Надо через динамический курсор, если, конечно, надо имено так(из хелпа билдера):

DECLARE my_cursor DYNAMIC CURSOR FOR SQLSA ;
integer Emp_id_var
string Emp_state_var = "MA"
string sqlstatement
sqlstatement = "SELECT emp_id FROM employee "&
+"WHERE emp_state = ?"
PREPARE SQLSA FROM :sqlstatement ;
OPEN DYNAMIC my_cursor using :Emp_state_var ;
FETCH my_cursor INTO :Emp_id_var ;
CLOSE my_cursor ;
...
Рейтинг: 0 / 0
10.09.2004, 11:06
    #32689099
gz
gz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Ikar...
3. я не знаю оракл, но тем не менее кусочек выражения " = ? and " меня смущает. Или это просто опечатка?

Ikar прав. Это не из Oracle.
Совет. Правилом должно быть анализ кода возврата каждого оператора, который обращается к базе, в частности, PREPARE, OPEN, FETCH.
Что-то типа
messagebox("...", "Ошибка при ..."~r~n~r~nКод ошибки = " + String(SQLSA.sqldbcode) + "~r~n~r~n" + String(SQLSA.SQLerrText))
...
Рейтинг: 0 / 0
10.09.2004, 11:18
    #32689135
gz
gz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Прошу прощения, выражение " = ? and " относится, к PowerBuilder, но не к Oracle.
...
Рейтинг: 0 / 0
10.09.2004, 11:33
    #32689181
gz
gz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
В запросе

leokolusSQL_Exp = "select " + String(ls_prcolumn) + " from amos." + String(ls_ptable) + " where " + String(ls_prcolumn) + " = ? and deptid = " + String(ls_dept) + ";"

Явно лишняя точка с запятой + ";".

Вообще говоря, лучше вместо "знаков вопроса" впечатать прямо в запрос значение переменных с учетом того, что если столбец в таблице - символьный, то надо заключить переменные в одиночные кавычки.
...
Рейтинг: 0 / 0
10.09.2004, 14:57
    #32689828
ЗоринАндрей
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
2 Ikar: зря смущает '=?'. почитайте про Dynamic SQL, про все четыре формата.
было бы честнее сказать "я про курсоры ничего не знаю поэтому считаю что курсор тут совершенно ни к чему"
то что через datastore можно сделать - не спорю, можно. Но не факт что лучше.

2 gz: а если сама строка ls_Item содержит апостроф или кавычки?
подстановку параметров в запрос умные люди не зря придумали.

2 leokolus: насчет точки с запятой gz прав.
проще всего для начала пройти под отладчиком внимательно наблюдая за sqldbcode после каждой операции.
...
Рейтинг: 0 / 0
10.09.2004, 15:18
    #32689889
Ikar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
ЗоринАндрей2 Ikar: зря смущает '=?'. почитайте про Dynamic SQL, про все четыре формата.
почитаю
ЗоринАндрей
было бы честнее сказать "я про курсоры ничего не знаю поэтому считаю что курсор тут совершенно ни к чему"
то что через datastore можно сделать - не спорю, можно. Но не факт что лучше.
голословное утверждение. Вы не знаете меня и не знаете, что я знаю, а что нет. А обсуждение что лучше - здесь: Курсор или datastore; Embedded SQL или объекты PB
Я предпочитаю использовать DataStore.
...
Рейтинг: 0 / 0
10.09.2004, 15:36
    #32689931
gz
gz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
ЗоринАндрей2 gz: а если сама строка ls_Item содержит апостроф или кавычки?
подстановку параметров в запрос умные люди не зря придумали.

Вы правы. С одиночными и двойными кавычками в PowerBuilder-е много приходится возиться.
...
Рейтинг: 0 / 0
11.09.2004, 03:05
    #32690558
leokolus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Всем большое спасибо, но есть одно НО которое я вам не сообщил и только сегодня я понял (не без вашей помощи конечно - за что ещё раз вам всем спасибо). Так вот в чём дело, начну по порядку.
Итак, в моей апликации используется две базы данных (SQL - локальная база и Oracle - лежит на сервере) и два вида транзакции (SQLCA и oracle_trans), так вот когда програмка стартует то она соединяется с локальной базой для того чтобы получить датавинду из которой будут браться все строковые переменные для подготовки SQL_Exp ="Select ......." , который будет применяться как раз для получения некой величиныХ из ремоте базы. При старте апликации также происходит соединение с базой на сервере и заполняеся другая датовинда которая тоже в дальнейшем используется в апликации, но уже в других целях. Всё это работает, но когда доходит дело для проверки величины в базе данных на сервере то происходит почемуто проверка в локальной базе и понятное дело что, я то думал, что проверка идёт в базе данных сервера и думал что код не работает.
Теперь такая просьба помогите заставить её работать так как мне надо т.е. что бы она соединялась с базой на сервере а не с локальной. Я немного поправил код, учёл ваши замечания:

String ls_prcolumn, ls_ptable, ls_dept, ls_Item, ls_find
String SQL_Exp

ls_prcolumn = String(sle_prcolumn.text)
ls_ptable = String(sle_prtable.text)
ls_dept = String(sle_dept.text) + "000001"
ls_Item = lb_notfound.SelectedItem()

DECLARE my_cursor DYNAMIC CURSOR FOR SQLSA ;
SQL_Exp = "Select " + String(ls_prcolumn) + " from amos." + String(sle_prtable.text) + " where " + String(ls_prcolumn) + " = " + String(ls_Item) + " and deptid = " + String(ls_dept)

PREPARE SQLSA FROM :SQL_Exp using oracle_trans; // вот тут она должна
// использовать соединение с базой сервера используя транзакцию
// oracle_trans, а она почемуто соединяется через SQLCA с местной базой

OPEN DYNAMIC my_cursor ; //USING :ls_Item;
FETCH my_cursor INTO :ls_find;

sle_find.text = ls_find

CLOSE my_cursor ;
...
Рейтинг: 0 / 0
11.09.2004, 16:11
    #32690677
gz
gz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
На этот раз синтаксис, вроде бы, правильный, хотя по-прежнему нет реакции на ошибки. Еще - не надо использовать функцию string() для преобразования string-овских переменных.
По всей видимости, дело в транзакции oracle_trans - почему Вы уверены, что она работающая ? До выполнения этого скрипта попробуйте что-нибудь совсем простое типа
select Col1 into :ls_Col1 from Tbl where ... using oracle_trans;
Естественно, с анализом кода возврата.
...
Рейтинг: 0 / 0
11.09.2004, 17:12
    #32690713
leokolus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Уверен что работает так как призапуске приложения происходит загрузка датавинды из таблицы которой нет в локальной базе, вернее есть но в ней в локалке только один ряд а в базе на сервере их много и я это вижу. Попробую простую команду с статическими переменными. для полной уверенности. Меня вот тут мысль осенила может мне сделать всю эту проверку в отдельном окне может приложение не понимает что от него хотят а может я неправилтно назначил транзакции. Приложение естественно делалось на базе другого, которое работало только на локальной базе, и соединение с базой было через User Object - Generated Database Connection Service, прямо из учебника по PB.
Я потом просто добавил

//Application -Global Variable

Transaction oracle_trans

// В User Object - of_connectdb()

oracle_trans = create transaction

oracle_trans.DBMS= "O84"
oracle_trans.ServerName = "unicom.world"
oracle_trans.Database = ""
oracle_trans.DBParm = ""
oracle_trans.LogId = "sample"
oracle_trans.LogPass = "newyear"
oracle_trans.AutoCommit = true

Connect using oracle_trans;

If oracle_trans.SQLCode <> 0 Then
MessageBox ("Cannot connect to Server Database", oracle_trans.SQLErrText )
Return 0
End If

Return 0

// В User Object - of_disconnectdb()

disconnect using oracle_trans ;
destroy oracle_trans
Return 0

Может тут криво всё сделано, кто может предложить более лучшее соединение к двум базам первой через SQLCA и ко второй через Oracle_Trance
моя благодарность просто не будет иметь границ
...
Рейтинг: 0 / 0
12.09.2004, 12:02
    #32690863
gz
gz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Синтаксис опять-таки правильный. Должно работать
Совет. Уберите временно динамические курсоры (а то окончательно перепугаете обитателей данного топика). И разберитесь в первую очередь с транзакциями, используя элементарные запросы.
...
Рейтинг: 0 / 0
12.09.2004, 17:38
    #32690976
leokolus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Всем большое спасибо. всё заработало
...
Рейтинг: 0 / 0
13.09.2004, 07:34
    #32691125
Геннадич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Это:
leokolus oracle_trans.AutoCommit = true

не есть хорошо. Вдруг сессия разваливается или приложение глюкает посреди серии инсертов или апдейтов, и половина данных в базе, а половины нет вообще, причём сколько внеслось, а сколько не внеслось большой вопрос. Если .AutoCommit = False, то всё откатится и можно будет их занести заново.
...
Рейтинг: 0 / 0
13.09.2004, 18:32
    #32692612
leokolus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Спасибо Геннадич, исправил.
...
Рейтинг: 0 / 0
14.09.2004, 20:16
    #32694636
Estets
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Ууупс, а если не секрет, не проще ли поставить AutoCommit = true и при необходимости открывать транзакции
Код: plaintext
EXECUTE IMMEDIATE "BEGIN TRANSACTION";
А не надеяться на дядю?
...
Рейтинг: 0 / 0
14.09.2004, 22:44
    #32694738
leokolus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Генналич спасибо большое ещё раз, но у меня прилада только для селектов, и никаких инсёртов быть и не должно. читая выбока необходимых данных их анализ и прочее прочее. Всем ещё раз спасибо я теперь дока в динамических курсорах. Я уже их понапихал во все кнопки какие только выдумал и работает пока без проблем а проблему я нашёл окончательно - у меня транзакция открывалась по нескольку раз и видимо друг друга прекрывала и не давала работать - это я так преметивно понимаю, я их посокращал и даже как мне показалось прилада работать быстрее стала.
Ещё раз всем спасибо
...
Рейтинг: 0 / 0
14.09.2004, 22:56
    #32694746
ЗоринАндрей
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
2 Estets: Вы вообще с Ораклом работали? Знаете как именно там работает AutoCommit?
То что Вы предлагаете применимо разве что к ASE и MSSQL, даже для Sybase ASA AutoCommit уже работает по-другому.
Если я правильно помню года три назад драйвер Oracle вообще игнорировал SQLCA.Autocommit напрочь.
...
Рейтинг: 0 / 0
14.09.2004, 23:15
    #32694757
Филипп
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
ЗоринАндрейЕсли я правильно помню года три назад драйвер Oracle вообще игнорировал SQLCA.Autocommit напрочь
По-моему и до сих пор...
...
Рейтинг: 0 / 0
15.09.2004, 06:50
    #32694825
Геннадич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Филипп ЗоринАндрейЕсли я правильно помню года три назад драйвер Oracle вообще игнорировал SQLCA.Autocommit напрочь
По-моему и до сих пор...

PB 9.0.1 Bild 7236 + Oracle 8.1.5 - в этой связке Autocommit работает.
...
Рейтинг: 0 / 0
15.09.2004, 19:03
    #32696468
Филипп
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
ГеннадичPB 9.0.1 Bild 7236 + Oracle 8.1.5 - в этой связке Autocommit работает.
Думаю, в основном у вас в голове.
И из опыта и согласно ВСЕЙ документации PB 9.0.1 AutoCommit database preference is IGNORED by Oracle.

Вот лист поддержанных database preference для O73 Oracle 7.3, O84 Oracle 8.x. и Oracle8i, O90 Oracle9i:
-Connect to Default Profile
-Keep Connection Open
-Read Only
-Shared Database Profiles
-SQL Terminator Character
-Use Extended Attributes
...
Рейтинг: 0 / 0
16.09.2004, 07:32
    #32696760
Геннадич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Филипп
Думаю, в основном у вас в голове.
И из опыта и согласно ВСЕЙ документации PB 9.0.1 AutoCommit database preference is IGNORED by Oracle.

Вот лист поддержанных database preference для O73 Oracle 7.3, O84 Oracle 8.x. и Oracle8i, O90 Oracle9i:
-Connect to Default Profile
-Keep Connection Open
-Read Only
-Shared Database Profiles
-SQL Terminator Character
-Use Extended Attributes

Я исполнил такой скрипт:
SQLCA.DBMS = "O84 Oracle8/8i (8.x.4+)"
SQLCA.LogId = "******"
SQLCA.LogPass = "*******"
SQLCA.ServerName = "******"
SQLCA.AutoCommit = true
SQLCA.DBParm = ""
connect;
Insert into test(id_, name_)
values (1, 'test')
;
disconnect;

И строка внеслась в базу. А написать можно что угодно и где угодно.
...
Рейтинг: 0 / 0
16.09.2004, 13:10
    #32697578
ЗоринАндрей
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Отлично.
А теперь то же самое но с
SQLCA.DBParm = "CommitOnDisconnect='No'"
...
Рейтинг: 0 / 0
16.09.2004, 16:08
    #32698194
Геннадич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамический курсор
Точно, если связь с БД разорвать корректно, то параметр SQLCA.DBParm = "CommitOnDisconnect='Yes'" комитит записи.
...
Рейтинг: 0 / 0
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Динамический курсор / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]