Вызов SQL хранимой процедуры с использованием предложения процедуры - PullRequest
1 голос
/ 06 августа 2020

Я новичок в коде VBA и изо всех сил стараюсь ознакомиться с ним для базы данных, которую я создаю. База данных занимается инвентаризацией ИТ-устройств и использует интерфейс MS Access Office 365 с серверной частью SQL 2017.

Вот что я пытаюсь выполнить sh. В базе данных мы не хотим удалять записи, просто архивируем их в другую таблицу. Для этого я создал хранимую процедуру в SSMS и убедился, что она выполняет свою работу правильно. Я хочу, чтобы VBA вызывал эту хранимую процедуру. Для этой процедуры мне нужно передать ему идентифицирующую информацию. В VBA я пытаюсь присвоить значение имени сервера из формы переменной, которую я могу передать в вызов хранимой процедуры. Я нашел слишком много примеров с использованием команды EXEC, но Access сообщает мне, что я должен использовать предложение Procedure. Я знаю, что мой код VBA ужасен, но, пожалуйста, помогите!

Private Sub Command148_Click()
   Dim SrvNameVar As String
   Dim strSQL As String
   Dim strParm As String
   SrvNameVar = Me.SrvName
   strParm = "PARAMETERS [Server Name] As CHAR;"

   Dim dbs As DAO.Database
   Dim qdf As DAO.QueryDef
   Set dbs = CurrentDb
   strSQL = strParm & "PROCEDURE dbo.sp_ArchiveServer [Server Name];"
   Set qdf = dbs.CreateQueryDef("SrvArchive", strSQL)

   dbs.Execute ("SrvArchive")
End Sub

Вот хранимая процедура, которая правильно работает в SSMS:

CREATE PROCEDURE sp_ArchiveServer @Server nvarchar(30) AS
   BEGIN TRANSACTION;
   INSERT INTO FSC.dbo.Archive_Servers ([SrvID],[SID],[SrvName],[Make],
            [Model],[SN],[SrvIP],[RemoteMgmt],[OSID],[IsDP],[IsIEMRelay],
            [IsGUP],[DatePurch],[WarrantyExp],[RAIDConfig],[PrintSrv],
            [ConnectedToUPS],[VirtHost],[VirtMachine])
   SELECT FSC.dbo.Servers.*
   FROM FSC.dbo.Servers
   WHERE FSC.dbo.Servers.SrvName = @Server;

   DELETE FROM FSC.dbo.Servers
   WHERE FSC.dbo.Servers.SrvName = @Server;

   COMMIT;

Спасибо за любую помощь!

Ответы [ 3 ]

3 голосов
/ 06 августа 2020

В настоящее время вы объединяете диалект MS Access SQL с диалектом SQL сервера. Только запросы MS Access SQL поддерживают PARAMETERS. Однако вы пытаетесь запустить серверный запрос SQL, в частности, для выполнения хранимой процедуры.

MS Access разрешает сквозные запросы к внутренним базам данных, поэтому вы можете настроить свой QueryDef (по умолчанию - Access backend) для подключения к базе данных MS SQL и затем выполнить команду EXEC. Все сквозные запросы должны соответствовать SQL диалекту серверной части.

Private Sub Command148_Click()
   Dim dbs As DAO.Database
   Dim qdf As DAO.QueryDef
   Dim SrvNameVar, strSQL As String

   SrvNameVar = Me.SrvName
   strSQL = "EXEC dbo.sp_ArchiveServer @Server='" & SrvNameVar &"'"

   Set dbs = CurrentDb
   Set qdf = dbs.CreateQueryDef("SrvArchive")

   ' ASSIGN ODBC DSN CONNECTION
   qdf.Connect = "ODBC; DATABASE=database; UID=user; PWD=password; DSN=datasourcename;" 
   qdf.SQL = strSQL
   qdf.Execute
End Sub

Чтобы эффективно использовать параметризацию, рассмотрите другой API, а именно ADO (с возможностью расширения до любой серверная база данных) вместо DAO (больше адаптировано для баз данных Access).

Private Sub Command148_Click()
   ' SET REFERENCE TO Microsoft ActiveX Data Object #.# Library
   Dim conn As ADODB.Connection, cmd As ADODB.Command
   Dim SrvNameVar As String

   SrvNameVar = Me.SrvName

   ' OPEN DRIVER OR DSN CONNECTION
   Set conn = New ADODB.Connection         
   conn.Open "DRIVER={SQL Server};server=servername;database=databasename;UID=username;PWD=password;"
   ' conn.Open "DSN=datasourcename"

   ' OPEN AND DEFINE COMMAND OBJECT
   Set cmd = New ADODB.Command     
   With cmd
       .ActiveConnection = conn
       .CommandText = "sp_ArchiveServer"
       .CommandType = adCmdStoredProc

       ' BIND PARAMETERS BY POSITION AND NOT NAME
       .Parameters.Append .CreateParameter("param1", adVarchar, adParamInput, 255, SrvNameVar)
       .Execute
   End With

   conn.close()
   Set cmd = Nothing: Set conn = Nothing
End Sub
1 голос
/ 07 августа 2020

Создайте сквозной запрос в конструкторе Access.

Вы можете ввести эту команду в запрос (sql представление). Итак, у вас есть промежуточный запрос, и он будет выглядеть так:

EXEC dbo.sp_ArchiveServer @Server='test'

Сохраните приведенный выше запрос. (убедитесь, что он проходит через запрос).

Хорошо, теперь ваш код VBA будет выглядеть так:

With CurrentDb.QueryDefs("qryPass")
   .SQL = "EXEC dbo.sp_ArchiveServer @Server='" & Me.SrvName & "'"
   .ReturnsRecords = False
   .Execute
End With
0 голосов
/ 07 августа 2020

Всем спасибо за помощь! Теперь, когда вы предоставили всю информацию, он работает. Для этого я последовал примеру Альберта, создав запрос Pass Through, а затем добавил в его код информацию от Parfait и ErikA относительно строки подключения. Затем я добавил простую команду MsgBox и команду Close Form, чтобы сделать ее более «красивой». Вот последний код, который сработал:

Private Sub Command148_Click()

With CurrentDb.QueryDefs("SrvQryPass")
   .Connect = "ODBC;DSN=ODBC_17;Description=FSC;Trusted_Connection=Yes;APP=Microsoft Office;DATABASE=FSC;Network=DBMSSOCN;"
   .SQL = "EXEC dbo.sp_ArchiveServer @Server='" & Me.SrvName & "'"
   .ReturnsRecords = False
   .Execute
End With

MsgBox "Archived!"
DoCmd.Close

End Sub
...