如何打开数据库“mydb”?登录请求.登录失败

本文关键字:登录 请求 失败 mydb 何打开 数据库 | 更新日期: 2023-09-27 18:07:51

我正在使用AdvancedInstaller在机器上安装SQL server express。AdvancedInstaller调用以下脚本(成功地)创建DB:

-- Inline SQL script
IF NOT EXISTS(SELECT name FROM master.sys.databases WHERE name = N'MyDB')
BEGIN
    create database MyDB
END

随着安装程序的继续,它还通过以下SQL脚本(成功地)创建表和存储过程:

USE[MyDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS(SELECT* FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Computers]') AND type in (N'U'))
BEGIN
CREATE TABLE[dbo].[Computers](
[ID]
[uniqueidentifier]
NOT NULL,
[Name] [nvarchar](50) NOT NULL,
CONSTRAINT[PK_Computers] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH(PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON[PRIMARY]
) ON[PRIMARY]
END
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS(SELECT* FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Computer_Add]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE [dbo].[Computer_Add] AS' 
END
GO

ALTER PROCEDURE[dbo].[Computer_Add] 
-- Add the parameters for the stored procedure here
@Name nvarchar(50), 
@ID uniqueidentifier 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
        set @ID = NEWID();
        -- insert the user into the DB.
        insert into[Computers]
        Values(
                @ID,
                @Name
                )
    END

使用这个DB,我有一个c# DLL有一个' DB。ConnectionWrapper的访问类。该类有一个名为"OpenConnection"的方法,其中包含以下内容:

private SqlConnection _connection;
public SqlConnection Connection
{
    get { return _connection; }
}
private void OpenConnection()
{
    _connection = new SqlConnection(connectionString);
    _connection.Open();
}

'connectionString'是一个字符串属性,包含以下内容:

Server=localhost''SQL_EXPRESS;Integrated security = SSPI; database=MyDB;

Joe在Administrators组中。用户"Joe"运行AdvancedInstaller程序,它首先安装SQL server express,然后AdvancedInstaller运行脚本来创建和安装DB。在安装(成功)完成后,Joe然后运行一个windows桌面程序,该程序使用DLL访问DB。访问数据库的代码可以完美地工作。然后Joe从服务器计算机注销。

但是,当"Bob"登录到服务器计算机(同样是管理员组中的另一个用户)并运行相同的windows桌面程序时,当代码试图打开与DB的连接时,会抛出以下异常:

System.Data.SqlClient.SqlException(0x80131904): Cannot open database "MyDB" requested by the user.The login failed.
Login failed for user 'MPS'Bob'.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at Db.ConnectionWrapper.OpenConnection()
我的问题是为什么?

EDIT1:

可能是因为我在创建DB时没有这个语句:

ALTER DATABASE [PMInfrastructure] SET  MULTI_USER 

Update to EDIT1: Database is already in MULTI_USER mode。-所以答案是no。

EDIT2

SQL server被AdvancedInstaller安装(成功),使用静默安装,只有这些命令行参数:

/q /IACCEPTSQLSERVERLICENSETERMS /ACTION=Install /FEATURES=SQLEngine /INSTANCENAME=SQL_EXPRESS /UpdateEnabled=False

已执行的SQL操作

(根据Raul Garcia的建议)

1> sqlcmd -E -S .'SQL_EXPRESS
2> go
1> USE [PMInfrastructure]
2> go
1> select name from sys.Login_token order by name
2> go
name
-------------------------------------------------
'Everyone
'LOCAL
BUILTIN'Administrators
BUILTIN'Users
BUILTIN'Users
CETRUS'SophosUser
MPS'Domain Users
MPS'SophosUser
NT AUTHORITY'Authenticated Users
NT AUTHORITY'INTERACTIVE
NT AUTHORITY'REMOTE INTERACTIVE LOGON
NT AUTHORITY'This Organization
public 
(13 rows affected)
1>
下面是我运行命令 时得到的结果
1> ALTER ROLE [db_datareader] ADD MEMBER [BUILTIN'Administrators]
2> ALTER ROLE [db_datawriter] ADD MEMBER [BUILTIN'Administrators]
3> GO
Msg 15151, Level 16, State 1, Server CETRUS'SQL_EXPRESS, Line 1
Cannot add the principal 'BUILTIN'Administrators', because it does not exist or
you do not have permission.
Msg 15151, Level 16, State 1, Server CETRUS'SQL_EXPRESS, Line 2
Cannot add the principal 'BUILTIN'Administrators', because it does not exist or
you do not have permission.
1>

SQL actions #2

C:'Program Files'Microsoft SQL Server'MSSQL12.SQL_EXPRESS'MSSQL'Binn

sqlcmd -E -S .'SQL_EXPRESS
use master
GO
CREATE LOGIN [BUILTIN'Administrators] FROM WINDOWS WITH DEFAULT_DATABASE=PMInfrastructure
GO
USE [PMInfrastructure]
GO
ALTER ROLE [db_datareader] ADD MEMBER [BUILTIN'Administrators]
ALTER ROLE [db_datawriter] ADD MEMBER [BUILTIN'Administrators]
GO
quit

SQL操作# 2结果:

C:'Program Files'Microsoft SQL Server'MSSQL12.SQL_EXPRESS'MSSQL'Binn>sqlcmd -E -S .'SQL_EXPRESS
1> use master
2> GO
Changed database context to 'master'.
1> CREATE LOGIN [BUILTIN'Administrators] FROM WINDOWS WITH DEFAULT_DATABASE=PMInfrastructure
2> GO
1> USE [PMInfrastructure]
2> GO
Changed database context to 'PMInfrastructure'.
1> ALTER ROLE [db_datareader] ADD MEMBER [BUILTIN'Administrators]
2> ALTER ROLE [db_datawriter] ADD MEMBER [BUILTIN'Administrators]
3> GO
Msg 15151, Level 16, State 1, Server CETRUS'SQL_EXPRESS, Line 1
Cannot add the principal 'BUILTIN'Administrators', because it does not exist or
you do not have permission.
Msg 15151, Level 16, State 1, Server CETRUS'SQL_EXPRESS, Line 2
Cannot add the principal 'BUILTIN'Administrators', because it does not exist or
you do not have permission.
SQL actions #3

我发现这个脚本:

USE master;
GO
CREATE LOGIN [BuiltIn'Users] FROM WINDOWS;
GO
USE PMInfrastructure;
GO
CREATE USER [BuiltIn'Users] FROM LOGIN [BuiltIn'Users];
GO
CREATE ROLE rSupport;
GO
EXEC sp_addrolemember 'rSupport', 'BuiltIn'Users';
GO
GRANT SELECT, INSERT,UPDATE, etc ON Mytable TO rSupport;
GO

我有两个问题:

SQL_A_3_1:由于sp_addRoleMember已弃用,所以我这样做了?

ALTER ROLE rSupport ADD MEMBER FROM USER [BuiltIn'Users]

SQL_A_3_2: I then did this ?

GRANT ALL TO rSupport;

谢谢

如何打开数据库“mydb”?登录请求.登录失败

当" Joe "安装SQL &当"Bob"运行应用程序时,"Joe"很可能是sysadmin组的成员,而"Bob"不是。

我注意到创建数据库的脚本不包括创建任何用户,这意味着只有sysadmin成员能够连接到数据库(不推荐设置)。

要知道我是否正确,请尝试使用sqlcmd运行为Joe &Bob(即从命令行运行sqlcmd -E -S .'sqlexpress).

SELECT name, type, usage FROM sys.login_token order by usage, type, name

如果我的理论是正确的,您将看到Joe有一个类似于这个的条目,表明他是sysadmin的成员,而Bob没有包含它:

sysadmin    SERVER ROLE GRANT OR DENY

你可以通过为Bob创建一个用户来解决这个问题(或者最好是为包含Bob &Joe),并授予他对数据库的必要访问权限。例如:

USE [myDB];
go
CREATE USER [MPS'MyDB_group];
go
ALTER ROLE [db_datareader] ADD MEMBER [MPS'MyDB_group];
ALTER ROLE [db_datawriter] ADD MEMBER [MPS'MyDB_group];
Go

如果我最初的假设不正确,请告诉我们,我们将推荐不同的策略来找出问题的根本原因。

谢谢,

消息——劳尔加西亚SQL安全

add-Migration后执行Update-Database命令。它将定位数据库,并且不会再出现登录失败。