|
|
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
Здравствуйте! Я использую для доступа к хранимой функции на сервере TableAdapter. Функция возвращает число тип real, т.е. явно скалярное значение. Тест в DataSet'е (контектное меню->Preview Data) проходит нормально, т.е.функция с тестовыми входными параметрами возвращает значение типа Object с правильным числовым значением. Но при попытке вызвать эту процедуру непосредственно внутри моей программы через объект Query упорно возвращается null. Убив несколько часов на эксперименты я выяснил, что если поменять у запроса ExecuteMode со Scalar на NonQuery, то все работает. Объясните, что происходит? В чем смысл тогда Scalar? Я по наивности считал, что это обозначает, что запрос возвращает единственное значение (не набор записей), а NonQuery - если он ничего не возвращает вообще (запросы типа delete * from ... ). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2007, 00:10 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
А заголовок SP и как ее дергаете посредством Query показать можно? _________________ "Helo, word!" - 17 errors 56 warnings Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2007, 08:50 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
Для экспериментов я создал простенькую хранимую процедуру, которая умножает входной параметр на 0.5 и возвращает это произведение: CREATE FUNCTION [dbo].[TestFunction](@val real ) RETURNS real AS BEGIN DECLARE @Result real set @Result =@val*0.5 RETURN @Result END В моем проекте на VB2005 я добавил Dataset, в котором создал новый Query по правой кнопочке мышки: "Add Query->поключение_к_серверу->Use existing Stored procedure->TestFunction->A single Value-> TestFunction" Затем, на формочке создал кнопочку и написал в обработке события Click следующее: Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim res As Object res = Me.QueriesTableAdapter1.TestFunction(25) Debug.WriteLine(res.ToString) End Sub При запуске в строке Debug.WriteLine... выскакивает ошибка "Object reference not set to an instance of an object.", т.е. res = null. Если поменять ExecuteMode со Scalar на NonQuery, или в мастере при создании вместо "A single Value" выбрать "No value", то возвращается 12.5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.12.2007, 18:16 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
Попробуйте Select @Result ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.12.2007, 21:23 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
Попробовал, вот что получилось: Msg 444, Level 16, State 3, Procedure TestFunction, Line 10 Select statements included within a function cannot return data to a client. Msg 455, Level 16, State 2, Procedure TestFunction, Line 10 The last statement included within a function must be a return statement. Да и не в этом дело. ИМХО, это какой-то косяк самой среды разработки... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2007, 17:12 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
b0ris98Попробовал, вот что получилось: Msg 444, Level 16, State 3, Procedure TestFunction, Line 10 Select statements included within a function cannot return data to a client. Msg 455, Level 16, State 2, Procedure TestFunction, Line 10 The last statement included within a function must be a return statement. Да и не в этом дело. ИМХО, это какой-то косяк самой среды разработки... Я не заметил что у вас функция. :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2007, 17:39 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
Только для очистки совести, что встрял. :) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Вы лучше верните резальсет через процедуры или работайте с параметрами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2007, 18:25 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
Select ВашаФункция(параметр) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2007, 18:27 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
Решил я тоже все попробовать ручками делать не используя все эти типизированные датасеты с типизированными тейбладаптерами. Сделал еще одну кнопочку и в обработчике клика прописал: Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim conn As New SqlConnection Dim sqlComm As SqlCommand Dim res As Object conn.ConnectionString = My.Settings.MyConnectionString conn.Open() sqlComm = New SqlCommand("dbo.TestFunction", conn) sqlComm.CommandType = CommandType.StoredProcedure sqlComm.Parameters.Add("val", SqlDbType.Real) sqlComm.Parameters("val").Value = 25 res = sqlComm.ExecuteScalar Debug.WriteLine(res.ToString) conn.Close() End Sub При запуске возникает "Object reference not set to an instance of an object", т.е. res = sqlComm.ExecuteScalar=null. Если res = sqlComm.ExecuteNonQuery, то возвращается -1 (а раньше через типизированный тейбладаптер возвращалось 12.5). После этого я модифицировал комманду, добавив селект: sqlComm = New SqlCommand("select dbo.TestFunction(@val)", conn) sqlComm.CommandType = CommandType.Text sqlComm.Parameters.Add("val", SqlDbType.Real) sqlComm.Parameters("val").Value = 25 res = sqlComm.ExecuteScalar Стало возвращаться 12.5, т.е. то что нужно. res = sqlComm.ExecuteNonQuery, тоже возвращает -1. Получается, что если требуется обратиться к функции на сервере, лучше это делать через "select function_name... ", а не напрямую (хотя напрямую тоже можно (см. выше), только как-то это неестественно получается ;-) ) Странно все это, некорректно как-то :-( А какие интересные глюки возникают, если хранимая процедура возвращает содержимое временных таблиц (select * from #a order by NameResource ) .... Эти визарды при создании типизированного тейбладаптера вообще не понимают, какие поля процедурой возвращаются. Как показали эксперименты, наличие знака "#" вводит в ступор... Кошмар ! :-( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2007, 19:52 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
b0ris98Получается, что если требуется обратиться к функции на сервере, лучше это делать через "select function_name... ", а не напрямую (хотя напрямую тоже можно (см. выше), только как-то это неестественно получается ;-) ) Я вам пр это и написал. b0ris98Странно все это, некорректно как-то :-( Очень даже корректно. Резальтсет и возворат функции - разные вещи. b0ris98А какие интересные глюки возникают, если хранимая процедура возвращает содержимое временных таблиц (select * from #a order by NameResource ) .... Эти визарды при создании типизированного тейбладаптера вообще не понимают, какие поля процедурой возвращаются. Как показали эксперименты, наличие знака "#" вводит в ступор... Кошмар ! :-( Это есть. Потому что никому не охота анализировать ваш код построения временной таблицы и взять на себя ответственность за его правильность. Вообще то подход простой - либо учимся пользоваться тем, что имеется или пишем свое и продаем. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2007, 20:04 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
Сахават Юсифов Я вам пр это и написал. Спасибо. Сахават Юсифов b0ris98Странно все это, некорректно как-то :-( Очень даже корректно. Резальтсет и возворат функции - разные вещи. Так это-то понятно, некорректность в смысле "там можно, но криво", а "тут - нельзя совсем". Если нет - так нет, а если да - так да ;-) Сахават Юсифов b0ris98А какие интересные глюки возникают, если хранимая процедура возвращает содержимое временных таблиц (select * from #a order by NameResource ) .... Эти визарды при создании типизированного тейбладаптера вообще не понимают, какие поля процедурой возвращаются. Как показали эксперименты, наличие знака "#" вводит в ступор... Кошмар ! :-( Это есть. Потому что никому не охота анализировать ваш код построения временной таблицы и взять на себя ответственность за его правильность. Вообще то подход простой - либо учимся пользоваться тем, что имеется или пишем свое и продаем. :) Да, с этим тоже пришлось помучиться. Но я догадался, как выйти из полжения ;-) . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2007, 20:21 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
[quot b0ris98] Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Код: plaintext 1. 2. 3. _________________ "Helo, word!" - 17 errors 56 warnings Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2007, 20:23 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
Просто добавить параметр ParameterDirection.ReturnValue Код: plaintext 1. 2. 3. 4. 5. P.S. А вообще-то лучше репу не морщить, а писать SELECT FROM dbo.TESTFUNCTION(@val) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2007, 20:51 |
|
||
|
TableAdapter и хранимые процедуры
|
|||
|---|---|---|---|
|
#18+
Все верно, специально проверил ;-) Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim conn As New SqlConnection Dim sqlComm As SqlCommand Dim res As Object Dim pret As New SqlParameter conn.ConnectionString = My.Settings.MyConnectionString conn.Open() sqlComm = New SqlCommand("dbo.TestFunction", conn) sqlComm.CommandType = CommandType.StoredProcedure SqlCommandBuilder.DeriveParameters(sqlComm) sqlComm.Parameters("@val").Value = 25 pret.Direction = ParameterDirection.ReturnValue pret.SqlDbType = SqlDbType.Real sqlComm.Parameters.Add(pret) sqlComm.ExecuteNonQuery res = sqlComm.Parameters("@RETURN_VALUE").Value Debug.WriteLine(res.ToString) conn.Close() End Sub Согласен на все 100%, что проще и понятнее все-таки использовать sql запрос "select function_name ..." Спасибо всем, кто откликнулся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2007, 21:29 |
|
||
|
|

start [/forum/topic.php?fid=17&gotonew=1&tid=1352486]: |
0ms |
get settings: |
6ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
144ms |
get topic data: |
9ms |
get first new msg: |
5ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
| others: | 204ms |
| total: | 442ms |

| 0 / 0 |
