Хранимые процедуры в VB

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
JumpingJack
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 61
Зарегистрирован: 25.01.2006 (Ср) 12:54

Хранимые процедуры в VB

Сообщение JumpingJack » 31.01.2006 (Вт) 18:05

Здравствуйте! Проблема в следующем:
На сервере есть процедура:
Код: Выделить всё
ALTER PROC test_proc
   @par1 char (4),
   @par2 varchar (100),   
   @par3 varchar (50), 
   @par4 varchar (50),   
   @par5 char (3), 
   @par6 char(3)
AS
INSERT INTO m_RemoteItem (par1, par2, par3, par4, par5, par6)
                  VALUES (@par1, @par2, @par3, @par4, @par5, @par6)
SELECT SCOPE_IDENTITY() AS [id]

Которая добавляет запись в таблицу, а затем возвращает значение его идентификатора.. на ссервере все работает нормально.. но из программы только добавлятеся запись, но ничего не возвращается.. вот мой код:
Код: Выделить всё
Dim rs As ADODB.Recordset
   Set rs = New ADODB.Recordset
   rs.CursorLocation = adUseClient

   With frmCreateApp
      rs.Open "test_proc '2', '2', '2', '2', '2', '2'", cn
      rs.MoveFirst
   End With
   t = rs.RecordCount
   MsgBox 12
   rs.Close


Хелп :)

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 31.01.2006 (Вт) 20:37

Может быть SET NOCOUNT ON тебе поможет :roll:

Мне, правда, не помогло...http://bbs.vbstreets.ru/viewtopic.php?t=21920
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 31.01.2006 (Вт) 23:24

Во-первых, непонятно, причем тут данный блок With...End With - лишний совершенно. Ну да не в нем дело, дело скорее всего в инструкции RS.MoveFirst - убери ее и посмотри, что получается. Далее, вместо .Open "test_proc ..." лучше все-таки писать "exec test_proc ...". Ну и конечно SET NOCOUNT тоже не помешает.

Если все равно ничего не получается, тогда полный код инициализации коннекта и рекордсета - в студию.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 01.02.2006 (Ср) 4:31

Я, конечно, всё понимаю, но всё же...

dim c as adodb.command
set c=new adodb.command
set c.activeconnection=cn
c.commandtext="test_proc"
c.commandtype=adcmdstoredproc
c.parameters.append c.createparameter("@par1",adchar, adparaminput,4,"2")
c.parameters.append c.createparameter("@par2",advarchar, adparaminput,100,"2")
c.parameters.append c.createparameter("@par3",advarchar, adparaminput,50,"2")
c.parameters.append c.createparameter("@par4",advarchar, adparaminput,50,"2")
c.parameters.append c.createparameter("@par5",adchar, adparaminput,3,"2")
c.parameters.append c.createparameter("@par6",adchar, adparaminput,3,"2")

with c.execute
.msgbox !id
.close
end with
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

JumpingJack
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 61
Зарегистрирован: 25.01.2006 (Ср) 12:54

Сообщение JumpingJack » 01.02.2006 (Ср) 12:08

Ну, изначально открытие вгылядело так:
Код: Выделить всё
   With frmCreateApp
      rs.Open "usp_RemoteInsertItem '" & .Text1.text & "', '" & .Text2.text & "', '" & _
               r1(Combo1.ListIndex) & "', '" & r1(Combo1.ListIndex) & "', '" & _
               .Text6.text & "', '" & .Text6.text & "'", cn
   End With

Я просто сократил, чтобы удобней читать было.. а with убрать забыл :)

GSerg, на .msgbox !id говорит что нету такого метода ;)
а вообще ругается на .close.. говорит что нельзя эту операцию производить на закрытом объекте :( примерно такая же фигня была и с рекордсетом..

И что такое SET NOCOUNT ON ?

И как делать "exec test_proc ..."? ..

JumpingJack
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 61
Зарегистрирован: 25.01.2006 (Ср) 12:54

Сообщение JumpingJack » 01.02.2006 (Ср) 12:35

а SET NOCOUNT ON действительно помог, GSerg, оба варианта работают, всем большое спасибо!

Но можно объяснить мне что такое SET NOCOUNT ON ? :)

И какйо вариант лучше использовать - ADODB.Command или ADODB.Recordset?

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 01.02.2006 (Ср) 13:38

SET NOCOUNT
Вообще же, поиск по сайту рулит.

Использовать в твоем конкретном случае лучше примерно вот такую конструкцию:
Код: Выделить всё
Dim Cmd As ADODB.Command, Rec As ADODB.Recordset
'...
Set Rec = Cmd.Execute("exec sp_MyProc", adCmdText)
If Not Rec Is Nothing Then
  ' Something was returned
  If (Rec.State And adStateOpen) > 0 Then
    ' We have records
    Do Until Rec.EOF
      ' Iterate through all rows
      ' ...
    Loop
    ' Now close it
    Rec.Close
  End If
End If

JumpingJack
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 61
Зарегистрирован: 25.01.2006 (Ср) 12:54

Сообщение JumpingJack » 01.02.2006 (Ср) 14:26

А зачем здесь надо Cmd.Execute? Когда можно просто делать Rec.Open и все работает..

И можно здесь:
Код: Выделить всё

   Dim c As ADODB.Command
   Set c = New ADODB.Command
   Set c.ActiveConnection = cn
   c.CommandText = "usp_RemoteInsertItem"
   c.CommandType = adCmdStoredProc
   c.Parameters.Append c.CreateParameter("@Year", adChar, adParamInput, 4, "2")
   c.Parameters.Append c.CreateParameter("@Name", adVarChar, adParamInput, 100, "2")
   c.Parameters.Append c.CreateParameter("@Reqv_Out", adVarChar, adParamInput, 50, "2")
   c.Parameters.Append c.CreateParameter("@Reqv_In", adVarChar, adParamInput, 50, "2")
   c.Parameters.Append c.CreateParameter("@Code_Out", adChar, adParamInput, 3, "2")
   c.Parameters.Append c.CreateParameter("@Code_In", adChar, adParamInput, 3, "2")

   With c.Execute
      MsgBox !ID
      .Close
   End With

Сделать какую-нибудь проверку на ошибке? Если да, то как, подскажите :)

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 01.02.2006 (Ср) 16:41

Будет ошибка - вылетит обычное исключение как всегда... Обрабатывается точно так же, как остальные ошибки...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

JumpingJack
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 61
Зарегистрирован: 25.01.2006 (Ср) 12:54

Сообщение JumpingJack » 01.02.2006 (Ср) 17:52

Код: Выделить всё
      .SendRs.MoveFirst
      For i = 0 To .SendRs.RecordCount - 1
         c.Parameters("@par1").Value = ItemID
         c.Parameters("@par2").Value = VarID
         c.Parameters("@par3").Value = SendBlankID
         c.Parameters("@par4").Value = .SendRs.Fields("f1").Value
         c.Parameters("@par5").Value = .SendRs.Fields("f1").Value
         With c.Execute
            .Close
         End With
         .SendRs.MoveNext
      Next i


Выдается ошибка на .close, говорит, что нельзя закрывать закрытый объект.. какой то бред :(

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 01.02.2006 (Ср) 18:40

Это не бред, это значит, что тебе рекордсет уже закрытым прилетает. Т.е. без записей.

JumpingJack
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 61
Зарегистрирован: 25.01.2006 (Ср) 12:54

Сообщение JumpingJack » 02.02.2006 (Чт) 11:08

Ммм.. с - это не рекордсет:
Код: Выделить всё
dim c as adodb.command
set c=new adodb.command
set c.activeconnection=cn
c.commandtext="test_proc"
c.commandtype=adcmdstoredproc

В чем может быть дело? Как мне сделать запуск в цикле? Он не хочет работать второй раз :(

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 02.02.2006 (Чт) 11:27

Ну если ты этот код в цикле используешь, то надо делать Set c = Nothing.
А если в цикле используется .Execute, то попробуй перед этим поставить .Prepared = True.
Lasciate ogni speranza, voi ch'entrate.

JumpingJack
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 61
Зарегистрирован: 25.01.2006 (Ср) 12:54

Сообщение JumpingJack » 02.02.2006 (Чт) 13:56

Я уже с рекордсетом разобрался! Большое спасибо всем за помощь :)

beat_swamp
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 107
Зарегистрирован: 05.10.2005 (Ср) 16:16

Сообщение beat_swamp » 15.03.2006 (Ср) 12:31

еще один вопрос по поставленной теме1

как передавать в хранимую процедуру в качестве параметра НАЗВАНИЕ ТАБЛИЦЫ? и как должен выглядеть запрос?
небольшой пример если можно1 заранее благодарен1

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 15.03.2006 (Ср) 12:54

Передавать текстом. varchar.
Запрос должен включать команду EXEC.
Только не надо так делать.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 15.03.2006 (Ср) 13:02

Название таблицы можно передать, как и любой другой параметр. Конкретно в MSSQL 2000 это тип sysname, который эквивалентен nvarchar(128).

Но если ты хочешь обращаться к переданной таблице в запросе, то сделать это можно только посредством динамического SQL (ну, не считая полного перебора всех таблиц в БД в одном монструозном блоке IF ... ELSE IF ...). Вкратце: не рекомендую, лучше в консерватории поправить.

beat_swamp
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 107
Зарегистрирован: 05.10.2005 (Ср) 16:16

Сообщение beat_swamp » 15.03.2006 (Ср) 16:41

офигеть1 +) ничего не понял1
вобщем у меня база данных MS Access
вот и нужно в хранимую процедуру (запрос) передать в виде параметра имя таблицы1
пример такого запроса:
Код: Выделить всё
SELECT * FROM <tablename>

<tablename> должен меняться взависимости от того какой параметр пришел из проги1 (ADO & VB)
вот и хотелось бы кусочек кода кот показывает как это имя передать1

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 15.03.2006 (Ср) 17:55

Надо было начинать с того, что access... В access - перепроектируй архитектуру.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 15.03.2006 (Ср) 17:58

Ы-ы-ы...
Ничего удивительного, что ты ничего не понял - не надо брать топик по MS SQL Server и продолжать его вопросом по MS Access.

Не думаю, что динамический SQL вообще возможен в твоем случае. Только присылать запрос с клиента, предварительно сформированный с необходимой тебе таблицей...


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

    TopList