azure - 当并非所有数据库都有用于连接到服务器的用户时,如何使用 SMO 列出 SQL Azure 服务器上的数据库?

标签 azure azure-sql-database smo

如果服务器上的一个数据库没有我用来创建 SMO 服务器连接的 SQL 用户,SMO 的 Server.Databases 将引发异常。

如果使用本地 SQL 2017 实例,我不会出现同样的错误。

例如:

我有一个名为“myazuresqlserver.database.windows.net”的 SQL Azure 服务器

  1. 在 master 上创建登录:

    使用密码创建登录 teSTLogin = 'ThisIsMySecretPassword'

  2. 创建 2 个数据库,DB1 和 DB2。

  3. 在 DB1 中创建用户“testuser”,但在 DB2 中创建:

    创建用户testuser用于登录teSTLogin

然后,使用 C# 和 SMO,我无法使用 teSTLogin 登录凭据获取该服务器的数据库列表 - 发生异常。

static void Main(string[] args)
{
    string[] names = GetDatabaseNames("myazuresqlserver.database.windows.net");
}

public static string[] GetDatabaseNames(string serverName)
{       
    ServerConnection connection = new ServerConnection(serverName, "testuser", "ThisIsMySecretPassword");
    var server = new Server(connection);
    return (from Database database in server.Databases
        where !database.IsSystemObject && !database.IsDatabaseSnapshot
        select database.Name
       ).ToArray();
}

异常(exception)情况是:

SqlException: The server principal "testlogin" is not able to access the database "DB2" under the current security context.
Cannot open database "DB2" requested by the login. The login failed. Login failed for user 'testlogin'.

我本希望不会抛出异常,而是 Server.Databases 仅包含所提供的凭据有效的数据库 - 这似乎是本地 SQL 2017 实例的行为。

最佳答案

我也遇到了同样的问题。就好像尝试查看 Server.Databases 会导致发生枚举,并且在这样做时会查看数据库属性 - 用户可能无权查询的属性。立即抛出异常。

我最终使用了一种不同的技术来获取数据库列表。我只是触发了一个 sql 查询:

SELECT name FROM sys.databases WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb');

要使上述查询起作用,用户必须具有访问 master 数据库的权限。这是我的代码块:

Dim Server As Server = New Server(New ServerConnection("myserver.server.net", "testlogin", "password"))
Dim databaseList As New DataTable
databaseList.Columns.Add("Name")

If Server.Edition = "SQL Azure" Then
    Dim SQLReader As SqlClient.SqlDataReader = Nothing
    Try
        SQLReader = Server.ConnectionContext.ExecuteReader("SELECT name FROM sys.databases WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb');")

        Do While SQLReader.Read = True
            databaseList.Rows.Add(Manager.Database.Sanitise(SQLReader, "name").ToString)
        Loop

        SQLReader.Close()
    Catch ex As Exception
        MsgBox(ex.Message)
    Finally
        If Not SQLReader Is Nothing Then
            SQLReader.Close()
        End If
    End Try
End If

关于azure - 当并非所有数据库都有用于连接到服务器的用户时,如何使用 SMO 列出 SQL Azure 服务器上的数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53493567/

相关文章:

azure - 如何从 Azure 表存储快速下载 1 亿行

Azure B2C 自定义策略授权端点给出 404

azure - 是否可以使用来自两个不同订阅的两个不同云服务的相同sql azure实例?

ios - 我如何只从 Azure 数据库中检索一列而不是选择 *

c# - SMO 中的连接超时

t-sql - Azure SQL Server 中的模糊搜索

azure - 如何配置 Azure 存储模拟器以与本地 SQL Server 配合使用

azure 自动化存储过程

sql-server - 为什么 sqlConnection.Close() 不关闭登录?

sql-server - 如何附加到powershell哈希表值?