外部子网 PC 中 SQL 服务器中的只读操作

Read Only Operations in SQL Server in a External Subnetwork PC

让每个人都了解情况:我们有一个已部署的 Windows 表单应用程序,用 C# 编码,并查询数据 from/to 一个 SQL 服务器 14 数据库。一切正常,直到我们需要将应用程序推送到主子网 192.168.0.X 之外的那一天,到 192.168.1.X.

与我的伙伴一起,我们相信在连接字符串中做一些修改可以解决我们前面遇到的第一个问题(没有连接到数据库;没有登录,没有简单的查询,什么都没有),沿着这个,这不允许我们使用存储过程或不使用存储过程将任何数据写入数据库。我们已经认为这可能是这个问题的根源之一,但事实并非如此,因为我们可以进行一些 SELECT 查询而不会发生任何戏剧性的变化。当然,在受影响的 PC 上。

之前是:

user id=myUser; password=myPass; server=myIP; Trusted_Connection=no; database=myDBName; connection timeout=30;

现在是:

Data Source=myServerName; Initial Catalog=myDatabaseName; User ID=myUsername;Password=myPassword; Server=IP, Port (if necessary);

Simple Select Query

异常的一些屏幕截图,打印在 MessageBox 中:

1st (and 3rd) Exception: Possible Truncated Data(这在第二个之后再次重复)

2nd Exception: Couldn't Open a Connection

我们已经检查了 TCP/IP、来自 SSMS 的端口配置、物理防火墙端口转发、conn 的更多变体。字符串,不同的 IPv4 配置,似乎没有任何效果(即使是新的超级用户,具有所有数据库和服务器权限)。所以我们离解决这个问题如此之近,又如此之远。

第 2 天编辑: 对受影响的代码(发生异常的地方)进行双重检查,即使有 @iakobski 提出的建议,它仍然是一样的。同样的例外,在同一个地方。唯一的区别是应用程序抛出它们的速度,因为它可以更快地关闭挂起的事务,并且异常得到处理,这要归功于 'finally' 子句。

此外,正如我在进行更深入的调试时注意到的那样,INSERT 或 UPDATE 本身并不是问题,而是存储过程的问题。因为它无法 Update/Select 使用 SQLSERVERPROCEDURE.SQLSERVER.Exec 形式的 SP 模块中的数据,但在插入日志条目时却没有(我相信这是执行的经典方式SQL 命令):

        SqlCommand cmd = new SqlCommand();
        con.ConnectionString = CadenaConexion;
        cmd.Connection = con;
        cmd.CommandText = "INSERT INTO LOG(LOG_ID_USUARIO,LOG_FECHA,LOG_PROCESO,LOG_CANTIDAD,LOG_PEDIDO,LOG_ITEM)" +
                          "VALUES(@log_id_usuario, @log_fecha, @log_proceso, @log_cantidad, @log_pedido, @log_item)";

        try
        {
            cmd.Parameters.Add("@log_id_usuario", SqlDbType.Int).Value = Log_id_usuario;
            cmd.Parameters.Add("@log_fecha", SqlDbType.DateTime).Value = Log_fecha;
            cmd.Parameters.Add("@log_proceso", SqlDbType.Text).Value = Log_proceso;
            cmd.Parameters.Add("@log_cantidad", SqlDbType.Int).Value = Log_cantidad;
            cmd.Parameters.Add("@log_pedido", SqlDbType.Int).Value = Log_pedido;
            cmd.Parameters.Add("@log_item", SqlDbType.Int).Value = Log_item;

            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();
            return true;
        }
        catch (Exception ex)
        {
            exSrc = "log";
            exMsg = ex.Message;
            exNota = "ERR_LogUsu01: No se ha podido Insertar el Registro a la Tabla Log";
            exStTr = ex.StackTrace;
            registrarEnLogErr();
            MessageBox.Show(ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
            return false;
        }
        finally { con.Close(); }

所以,如果昨天我很确定这个名为 SQLSERVERPROCEDURE.dll 的小文件与它处理的存储过程有直接关系在这里做,我现在 sure-r。不知何故,它可能正在使用旧的连接字符串,但我不知道如何更改它,因为对该文件进行的每次调用都将 Conn.String 称为 "DBSQL"(尝试更改它时调用,放置 SharedData.Instance().StringConexion,还有一个 'cn' 变量 [with ToString()],没有运气。说 Conn.String 未定义)。查看带有 .dll 调用的 SP 中的定义,以及 .dll 文件本身:

更新模块:

        SqlConnection cn = new SqlConnection(SharedData.Instance().StringConexion);

        try
        {
            Dictionary<string, object> param = new Dictionary<string, object>();
            param.Add("@nta_venta", nta_venta);
            param.Add("@item", item);
            param.Add("@cantidad", cantidad);
            cn.Open();
            SQLSERVERPROCEDURE.SQLSERVER.Exec("DBSQL", SP, param);
            cn.Close();
        }
        catch (Exception ex)
        {
            exSrc = this.Name;
            exMsg = ex.Message;
            exNota = "ERR_Corte02: Pedido: " + nta_venta + "-" + item + " con Falta de Parámetros válidos en Actualiza";
            exStTr = ex.StackTrace;
            registrarEnLogErr();
            MessageBox.Show(ex.Message);
        }
        finally { cn.Close(); }

DLL 文件:VS 上的标题:SQLSERVER (来自元数据)

#region Ensamblado SQLSERVERPROCEDURE, Version=1.0.0.0, Culture=neutral, 

PublicKeyToken=null
// C:\Users\User\source\repos\MY-APP\packages\EXECSQLSERVERPROCEDURE.2.0.0\lib\net40\SQLSERVERPROCEDURE.dll
#endregion

using System.Collections.Generic;
using System.Data;

namespace SQLSERVERPROCEDURE
{
    public static class SQLSERVER
    {
        public static DataTable Exec(string NombreConexion, string Procedimiento, Dictionary<string, object> VariableYValores, DataTable dt = null);
        public static DataSet Exec(string NombreConexion, string Procedimiento, Dictionary<string, object> VariableYValores, DataSet ds = null);
        public static void Exec(string NombreConexion, string Procedimiento, Dictionary<string, object> VariableYValores);
    }
}

第一个 StackTrace(不再有效,因为它已通过 re-done 打开和关闭语句解决):

Excepción producida: 'System.Data.SqlClient.SqlException' en System.Data.dll
El subproceso 0x3f5c terminó con código 0 (0x0).
Excepción producida: 'System.Data.SqlClient.SqlException' en SQLSERVERPROCEDURE.dll
Excepción producida: 'System.InvalidOperationException' en System.Data.dll
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Transactions.resources\v4.0_4.0.0.0_es_b77a5c561934e089\System.Transactions.resources.dll' cargado. El módulo se compiló sin símbolos.
System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Excepción no controlada</Description><AppDomain>myApp.exe</AppDomain><Exception><ExceptionType>System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>No está autorizado a cambiar la propiedad 'ConnectionString'. El estado actual de la conexión es abierta.</Message><StackTrace>   en System.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key)
   en System.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
   en MY_APP.Class.log_errores.INSERT_log_err() en C:\Users\User\Source\Repos\MY-APP\MY APP\Class\log_errores.cs:línea 34
   en MY_APP.PrcsCorte.registrarEnLogErr() en C:\Users\User\Source\Repos\MY-APP\MY APP\PrcsCorte.cs:línea 378
   en MY_APP.PrcsCorte.cargarPedido(Int32 nv, Int32 it) en C:\Users\User\Source\Repos\MY-APP\MY APP\PrcsCorte.cs:línea 267
   en MY_APP.PrcsCorte.PrcsCorte_Activated(Object sender, EventArgs e) en C:\Users\User\Source\Repos\MY-APP\MY APP\PrcsCorte.cs:línea 39
   en System.Windows.Forms.Form.OnActivated(EventArgs e)
   en System.Windows.Forms.Form.set_Active(Boolean value)
   en System.Windows.Forms.Form.WmActivate(Message&amp;amp; m)
   en System.Windows.Forms.Form.WndProc(Message&amp;amp; m)
   en System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp;amp; m)
   en System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;amp; m)
   en System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)</StackTrace><ExceptionString>System.InvalidOperationException: No está autorizado a cambiar la propiedad 'ConnectionString'. El estado actual de la conexión es abierta.
   en System.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key)
   en System.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
   en MY_APP.Class.log_errores.INSERT_log_err() en C:\Users\User\Source\Repos\MY-APP\MY APP\Class\log_errores.cs:línea 34
   en MY_APP.PrcsCorte.registrarEnLogErr() en C:\Users\User\Source\Repos\MY-APP\MY APP\PrcsCorte.cs:línea 378
   en MY_APP.PrcsCorte.cargarPedido(Int32 nv, Int32 it) en C:\Users\User\Source\Repos\MY-APP\MY APP\PrcsCorte.cs:línea 267
   en MY_APP.PrcsCorte.PrcsCorte_Activated(Object sender, EventArgs e) en C:\Users\User\Source\Repos\MY-APP\MY APP\PrcsCorte.cs:línea 39
   en System.Windows.Forms.Form.OnActivated(EventArgs e)
   en System.Windows.Forms.Form.set_Active(Boolean value)
   en System.Windows.Forms.Form.WmActivate(Message&amp;amp; m)
   en System.Windows.Forms.Form.WndProc(Message&amp;amp; m)
   en System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp;amp; m)
   en System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;amp; m)
   en System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)</ExceptionString></Exception></TraceRecord>
Excepción no controlada del tipo 'System.InvalidOperationException' en System.Data.dll
No está autorizado a cambiar la propiedad 'ConnectionString'. El estado actual de la conexión es abierta.

El subproceso 0x2e54 terminó con código 0 (0x0).
El subproceso 0x42cc terminó con código 0 (0x0).
El subproceso 0x3d84 terminó con código 0 (0x0).

Excepción no controlada: System.InvalidOperationException: No está autorizado a cambiar la propiedad 'ConnectionString'. El estado actual de la conexión es abierta.
   en System.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key)
   en System.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
   en MY_APP.Class.log_errores.INSERT_log_err() en C:\Users\User\Source\Repos\MY-APP\MY APP\Class\log_errores.cs:línea 34
   en MY_APP.PrcsCorte.registrarEnLogErr() en C:\Users\User\Source\Repos\MY-APP\MY APP\PrcsCorte.cs:línea 378
   en MY_APP.PrcsCorte.cargarPedido(Int32 nv, Int32 it) en C:\Users\User\Source\Repos\MY-APP\MY APP\PrcsCorte.cs:línea 267
   en MY_APP.PrcsCorte.PrcsCorte_Activated(Object sender, EventArgs e) en C:\Users\User\Source\Repos\MY-APP\MY APP\PrcsCorte.cs:línea 39
   en System.Windows.Forms.Form.OnActivated(EventArgs e)
   en System.Windows.Forms.Form.set_Active(Boolean value)
   en System.Windows.Forms.Form.WmActivate(Message& m)
   en System.Windows.Forms.Form.WndProc(Message& m)
   en System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   en System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   en System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
El programa '[17180] myApp.exe' terminó con código 0 (0x0).

第二个 StackTrace:

'myApp.exe' (CLR v4.0.30319: DefaultDomain): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: DefaultDomain): 'C:\Users\User\Source\Repos\MY-APP\MY APP\bin\Debug\myApp.exe' cargado. Símbolos cargados.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Data.resources\v4.0_4.0.0.0_es_b77a5c561934e089\System.Data.resources.dll' cargado. El módulo se compiló sin símbolos.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Transactions\v4.0_4.0.0.0__b77a5c561934e089\System.Transactions.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.EnterpriseServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.EnterpriseServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.Wrapper.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Runtime.Caching\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Runtime.Caching.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Numerics\v4.0_4.0.0.0__b77a5c561934e089\System.Numerics.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms.resources\v4.0_4.0.0.0_es_b77a5c561934e089\System.Windows.Forms.resources.dll' cargado. El módulo se compiló sin símbolos.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_es_b77a5c561934e089\mscorlib.resources.dll' cargado. El módulo se compiló sin símbolos.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\Users\User\Source\Repos\MY-APP\MY APP\bin\Debug\SQLSERVERPROCEDURE.dll' cargado. No se encuentra el archivo PDB o no se puede abrir.
'myApp.exe' (CLR v4.0.30319: myApp.exe): 'C:\Program Files (x86)\Microsoft Visual Studio17\Community\Common7\IDE\PrivateAssemblies\Runtime\Microsoft.VisualStudio.Debugger.Runtime.dll' cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador 'Sólo mi código' está habilitada.
Excepción producida: 'System.Data.SqlClient.SqlException' en System.Data.dll
Excepción producida: 'System.Data.SqlClient.SqlException' en System.Data.dll
El subproceso 0x1184 terminó con código 0 (0x0).
El subproceso 0xfe0 terminó con código 0 (0x0).
El subproceso 0xc70 terminó con código 0 (0x0).
El subproceso 0x4b64 terminó con código 0 (0x0).
El subproceso 0x5e04 terminó con código 0 (0x0).
El subproceso 0x3ef4 terminó con código 0 (0x0).
El subproceso 0x3b58 terminó con código 0 (0x0).
El subproceso 0x480c terminó con código 0 (0x0).
Excepción producida: 'System.Data.SqlClient.SqlException' en SQLSERVERPROCEDURE.dll
El subproceso 0x48f0 terminó con código 0 (0x0).
El subproceso 0x4238 terminó con código 0 (0x0).
Excepción producida: 'System.Data.SqlClient.SqlException' en System.Data.dll
El subproceso 0x5ddc terminó con código 0 (0x0).
El subproceso 0x5184 terminó con código 0 (0x0).
El subproceso 0x3074 terminó con código 0 (0x0).
El subproceso 0x3bdc terminó con código 0 (0x0).
El subproceso 0x55f4 terminó con código 0 (0x0).
El subproceso 0x44b4 terminó con código 0 (0x0).
El programa '[18484] myApp.exe' terminó con código 0 (0x0).

SSMS 截图:

Server Roles

Database Roles

Permissions

Settings and Status

问题已在您的错误消息中显示,您无法更改现有连接上的连接字符串。每次要访问数据库时都应该始终打开一个新连接,并在完成后立即将其处理掉,方法是将其包含在一个 using 块中:

using(SqlConnection connection = new SqlConnection(<connection string>))
{
    connection.Open();
    // database interaction here
}

连接将在离开 using 块时被处理掉。不要担心您正在创建大量连接并认为它会影响性能,连接池会为您处理。

首先,很抱歉这么晚才发布。其次,在所有答案中,我可以说我做了以下(并且有效):

  • 向所有执行操作的数据库添加了 using
  • 添加了一个 IsServerConnected 方法,以此作为参考: What's the best way to test SQL Server connection programmatically? 在我的 错误日志 方法中
  • (这是真正的答案)转到 App.config 文件并检查 EXECSQLSERVERPROCEDURE 插件使用的特殊连接字符串,并更新了数据库连接凭证

有时候,最令人头疼的问题都有令人难以置信的简单答案,你不觉得吗?

谢谢大家!