2017-01-17 1 views
2

Хотя я много работал с VBA на протяжении многих лет, я нахожу свою первую возможность использовать его для подключения к MS SQL базы данных и выполнить несколько различных запросов. Эта проблема заключается в том, что возвращенный набор результатов имеет именованные поля. В настоящее время, после некоторой борьбы с параметрами, я получил свой запрос. Он выполняет параметризованную хранимую процедуру с одним входным и двумя выходными параметрами.Могут ли поля возвращаться с именами в ADODB Result для выходной параметризованной хранимой процедуры

Вот зр:

ALTER PROCEDURE [dbo].[uspGetFamily] 
-- Add the parameters for the stored procedure here 
@FormulaNum  varchar(10), 
@FamilyID  bigint OUTPUT, 
@FamilyName  varchar(20) OUTPUT 
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

-- Insert statements for procedure here 
SELECT @FamilyID = v.FamilyID, @FamilyName = f.FamilyName FROM utblVariants as v 
    INNER JOIN dbo.utblFamilies as f 
    ON v.FamilyID = f.FamilyID 
WHERE v.FormulaNo = @FormulaNum 

SELECT @FamilyID, @FamilyName 
END 

А вот соответствующая часть кода VBA:

'open the connection to the database 
oConn.Open sConnString 

'setup the command parameter including the sp parameters 
With oCmd 
    .ActiveConnection = oConn 
    .CommandText = "BWDG.dbo.uspGetFamily" 
    .CommandType = adCmdStoredProc 
    'Formul number input parameter 
    .Parameters.Append .CreateParameter("@FormulaNum", adVarChar, adParamInput, 10, Trim(txtFromFormula.Value)) 
    'Formula Family ID returned as an output parameter 
    .Parameters.Append .CreateParameter("@FamilyID", adBigInt, adParamOutput, , Null) 
    'Formula Family name returned as an output parameter 
    .Parameters.Append .CreateParameter("@FamilyName", adVarChar, adParamOutput, 20, Null) 

End With 

'Get the resultset from the executed connection command 
oRS.Open oCmd 
'Set oRS = oConn.Execute(sExecString) 

If Not (oRS.EOF And oRS.BOF) Then 
    oRS.MoveFirst 
    'Parse the data to corresponding variables 
    iFromFamilyID = oRS(0) 
    sFromFamily = oRS(1) 

    lblFromFamily.Caption = sFromFamily 

End If 

Я хотел бы элементы результирующего набора ORS, чтобы вернуться с полями имени , В настоящее время имена полей пусты.

Этот код будет использоваться повторно (я просто выполняю тестирование разработки в настоящее время), и я хотел бы, чтобы он был более интуитивным, не только для меня, но и для других, которые могут в конечном итоге сохранить это.

Итак, вопрос, есть ли способ, чтобы набор результатов был заполнен так, чтобы поля были названы и, таким образом, разрешали ссылки на объекты вместо имен индекса?

+1

В вашей хранимой процедуре, например, colu МНБ. 'SELECT @FamilyID как FamilyID, @FamilyName как FamilyName' –

+0

^^ это. теперь, я не уверен, почему вам нужно «выбрать» эти два значения, учитывая, что ваши параметры * уже содержат возвращаемые значения - набор записей является избыточным. Просто объявляйте свои два параметра out как локальные переменные вместо их вложения, и они должны иметь свое значение после запуска 'cmd.Execute'.Кроме того, пожалуйста, прочитайте [* Неправильный код неправильно] * (https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/) для почему 'oCmd' и' oRS' и 'iFromFamilyID' и' sFromFamily' являются ужасными идентификаторами. –

ответ

1

У вас есть параметры out ... зачем вам нужно select их и вернуть их в набор записей вообще?

'... 

Dim familyId As ADODB.Parameter 
Dim familyName As ADODB.Parameter 

With cmd 
    '... 
    Set familyId = .CreateParameter("@FamilyID", adBigInt, adParamOutput, , Null) 
    .Paramters.Append familyId 
    Set familyName = .CreateParameter("@FamilyName", adVarChar, adParamOutput, 20, Null) 
    .Parameters.Append familyName 

    .Execute 
End With 

И тогда вы можете получить затраченные значения параметров прямо:

lblFromFamily.Caption = familyName.Value 

Нет записей нужно увлекаться.


Альтернативно, если вы хотите выбрать результаты и вернуть Recordset, вы можете сделать это, - но потом, падение out параметров!

В этом случае вам нужно будет использовать псевдонимы ваших столбцов, as was already mentioned in comments.

SELECT @FamilyID FamilyID, @FamilyName FamilyName 

(As ключевое слово может быть включена, по желанию, если вы предпочитаете)

И тогда вы можете получить поля по имени:

familyId = rs.Fields("FamilyID").Value 
familyName = rs.Fields("FamilyName").Value 

Или, используя эквивалентную стенографии " bang "(при условии, что псевдонимы столбцов являются законными идентификаторами VBA):

familyId = rs!FamilyID 
familyName = rs!FamilyName 
+1

Это также мой первый набег на запись хранимых процедур с использованием выходных параметров, так что у вас есть все вопросы о том, почему я бы это сделал, на что можно ответить только «невежество!». :) – MikeA

+1

Спасибо всем. Ваша помощь была бесценной! Я рассмотрю вышеупомянутую статью и попытаюсь работать более чисто и эффективно в будущем. В моей защите я не являюсь чистым кодером (как будто вы этого еще не осознавали). Мой опыт в промышленной автоматизации с системами PLC, HMI и SCADA. Я больше вступаю в индустриальную сторону программного обеспечения, и у меня есть взрыв, который изучает новые вещи и работает в новых средах и с различными инструментами и процессами. Еще раз спасибо за помощь, ВЫ ВСЕГДА! – MikeA

+0

FYI вы можете щелкнуть полый зеленый флажок рядом с этим ответом, чтобы отметить его как «принятый» –