SQL Management Studio 2012 с настройкой строки подключения Excel vba

#sql #sql-server #vba #excel

#sql #sql-сервер #vba #excel

Вопрос:

Я хотел бы настроить код vba, который будет подключаться к sql Management studio 2012 и запускать запрос, который я бы указал в коде vba. Я прочитал здесь все похожие вопросы о переполнении стека, но когда я пытаюсь их воспроизвести, я всегда получаю сообщение об ошибке, обычно из-за сбоя входа пользователя в систему.

Я думаю, что я неправильно настраиваю строковое соединение. Кроме того, мне потребуется проверка подлинности пользователя с помощью проверки подлинности Windows.

Я знаю имя базы данных, имя сервера и свое имя пользователя.

Это код, который я использую, и который выдает мне ошибку.

 Sub ConnectionExample6()
 Dim cnn As ADODB.Connection
 Dim rs As ADODB.Recordset

 Set cnn = New ADODB.Connection

 ' Open a connection by referencing the ODBC driver.
 cnn.ConnectionString = "driver={SQL Server};" amp; _
  "server=SERVER NAME;uid=USER ID;pwd=MyPassword;database=DATABASE NAME"
 cnn.Open

' Create a Recordset by executing an SQL statement.
 Set rs = cnn.Execute("Select top 100 * from "TABLE NAME" aac " amp; _
 "where aac.EffectiveDate = '10/04/16'")

 ' Close the connection.
 rs.Close

End Sub
  

Может кто-нибудь рассказать мне о строке подключения и о том, как настроить ее шаг за шагом? Спасибо.

Комментарии:

1. ошибка: ошибка времени выполнения ‘-2147217843 (80040e4d)’: [Microsoft] [Драйвер ODBC SQL Server] Не удалось войти в систему для пользователя ‘Идентификатор ПОЛЬЗОВАТЕЛЯ’

2. Если вы хотите использовать проверку подлинности Windows, не указывайте идентификатор пользователя / пароль в строке подключения.

3. Mat прибил это, просто убедитесь, что все пользователи, которые будут использовать этот макрос, имеют общедоступный доступ к серверу SQL и базе данных. Или добавьте их в группу в домене, у которого есть доступ.

4. Потрясающе! Большое вам спасибо, это работает!!

Ответ №1:

Проверка подлинности

Если вы подключаетесь к SQL Server, вам следует предпочесть проверку подлинности Windows, если она доступна: вы создаете логин на уровне сервера для группы пользователей Active Directory, а затем создаете пользователя, прошедшего проверку подлинности Windows, в своей базе данных, используя этот логин.

Таким образом, вы сохраняете пароли и имена пользователей из жестко запрограммированных строк и позволяете сети обрабатывать аутентификацию.

Предполагая, что вы не хотите хранить пароли в десятках копий рабочих книг с поддержкой макросов по всей сети, вы захотите использовать проверку подлинности Windows.

 Integrated Security=SSPI; Persist Security Info=True;
  

Сервер

Строки подключения раздражают — кажется, есть разные форматы / формулировки для каждой отдельной вещи, которая может их анализировать!

Поскольку вы используете ADODB, вам потребуется указать поставщика, источник данных и, при необходимости, начальный каталог:

 Provider=SQLOLEDB.1; Data Source=SQL Server instance name; Initial Catalog=Database name;
  

Кто?

Каждое соединение можно отслеживать на сервере; при создании строки подключения вы можете дополнительно указать идентификатор рабочей станции, чтобы идентифицировать компьютер, к которому подключено соединение.

 Workstation ID=computer name;
  

Вы можете получить имя компьютера, выбрав значение переменной среды, используя Environ$ :

 Private Function GetWorkstationId() As String
    GetWorkstationId = Environ$("ComputerName")
End Function
  

Учитывая имя экземпляра SQL Server SomeSqlServer , имя базы SomeDatabase данных и использование проверки подлинности Windows, строка подключения ADODB будет выглядеть следующим образом:

 Dim connString As String
connString = "Provider=SQLOLEDB.1; Data Source=SomeSqlServer; Initial Catalog=SomeDatabase; Integrated Security=SSPI; Persist Security Info=True;"
  

Задана проверка подлинности SQL (с жестко заданным именем пользователя и паролем) для SomeUser с SomePassword :

 connString = "Provider=SQLOLEDB.1; Data Source=SomeSqlServer; Initial Catalog=SomeDatabase; UID=SomeUser; PWD=SomePassword;"
  

Команды

Вы не хотите объединять произвольный пользовательский ввод в предложение WHERE; избегайте выполнения строки SQL непосредственно из ADODB.Connection объекта.

Вместо этого создайте ADODB.Command и параметрируйте свой запрос.

 Dim sql As String
sql = "SELECT Foo, Bar FROM dbo.FooBars WHERE Foo = ? AND DateInserted > ?"
  

Здесь у нас есть 2 параметра.

Сначала мы создаем команду:

 Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
cmd.CommandText = sql
  

Затем его параметры, предполагая, что у нас есть их соответствующие значения в param1Value и param2Value локальных переменных:

 Dim param1 As ADODB.Parameter ' a string parameter
Set param1 = New ADODB.Parameter
param1.Type = adVarWChar
param1.Direction = adParamInput
param1.Size = Len(param1Value)
param1.Value = param1Value
cmd.Parameters.Append param1

Dim param2 As ADODB.Parameter ' a date parameter
Set param2 = New ADODB.Parameter
param2.Type = adDate
param2.Direction = adParamInput
param2.Value = param2Value
cmd.Parameters.Append param2
  

Затем мы извлекаем набор записей, выполняя команду:

 Dim results As ADODB.Recordset
Set results = cmd.Execute
  

Конечно, это выглядит очень многословно, но его можно легко преобразовать в функции, предназначенные для создания параметра со значением определенного типа.

В результате вы избегаете этой ситуации, поскольку вы больше не выполняете произвольный пользовательский ввод, объединенный в запрос:

XKCD: использование Mom

Комментарии:

1. Отличный ответ, лучший мультфильм