¿Cuál es el mejor método para comprobar si existe un archivo de un Servidor SQL server 2005 procedimiento almacenado?

StackOverflow https://stackoverflow.com/questions/16634

  •  08-06-2019
  •  | 
  •  

Pregunta

Hemos utilizado los "indocumentados" xp_fileexist procedimiento almacenado durante años en SQL Server 2000 y no tenía problemas con él.En 2005, parece que se modifican el comportamiento ligeramente siempre devuelve un 0 si la ejecución de la cuenta de usuario no es un administrador de sistemas.También parece devolver un cero si el servicio de SQL Server se ejecuta bajo la cuenta LocalSystem y está intentando comprobar un archivo en la red.

Me gustaría alejarse de xp_fileexist.¿Alguien tiene una mejor forma de comprobar la existencia de un archivo en una ubicación de red desde el interior de un procedimiento almacenado?

¿Fue útil?

Solución

Tal vez un procedimiento almacenado CLR es lo que usted está buscando.Estos se utilizan generalmente cuando usted necesita para interactuar con el sistema de alguna manera.

Otros consejos

Usted tendrá que marcar el CLR como EXTERNAL_ACCESS con el fin de obtener acceso al Sistema.Espacio de nombres es, sin embargo, como van las cosas, que no es una mala manera de ir sobre ella.

SEGURO es el conjunto de permisos predeterminado, pero es altamente restrictiva.Con la configuración de seguridad, puede tener acceso sólo a los datos de una base de datos local para realizar la lógica computacional en los datos.EXTERNAL_ACCESS es el siguiente paso en la jerarquía de permisos.Esta opción de configuración permite el acceso a recursos externos, tales como el sistema de archivos, Visor de Eventos de Windows y servicios Web.Este tipo de recursos no sea posible el acceso en SQL Server 2000 y versiones anteriores.Este conjunto de permisos también restringe las operaciones, tales como puntero de acceso que afectan a la solidez de su asamblea.El conjunto de permisos UNSAFE asume la plena confianza de la asamblea y por lo tanto no impone "Código de Seguridad de Acceso a las" limitaciones.Este valor es comparable a la forma en que los procedimientos almacenados extendidos función—usted asume todo el código es seguro.Sin embargo, esta configuración no restringir la creación de los ensamblados a los usuarios que tienen permisos de sysadmin.Microsoft recomienda que evite la creación de inseguro asambleas tanto como sea posible.

Todavía creo que un procedimiento CLR podría ser la mejor apuesta.Por lo tanto, estoy aceptando que responder.Sin embargo, yo no soy tan brillante o es extremadamente difícil de implementar.Nuestro servicio de SQL Server se ejecuta bajo una cuenta local porque, según Mircosoft, que es la única manera de conseguir un iSeries servidor vinculado de trabajo de una de 64 bits de SQL Server 2005 instancia.Cuando cambiamos el servicio de SQL Server para que se ejecute con una cuenta de dominio, el xp_fileexist comando funciona bien para los archivos que se encuentran en la red.

He creado este procedimiento almacenado CLR y construido con el nivel de permiso Externo y lo firmó:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Security.Principal;

public partial class StoredProcedures
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void FileExists(SqlString fileName, out SqlInt32 returnValue)
    {
        WindowsImpersonationContext originalContext = null;

        try
        {
            WindowsIdentity callerIdentity = SqlContext.WindowsIdentity;
            originalContext = callerIdentity.Impersonate();

            if (System.IO.File.Exists(Convert.ToString(fileName)))
            {
                returnValue = 1;
            }
            else
            {
                returnValue = 0;
            }
        }
        catch (Exception)
        {
            returnValue = -1;
        }
        finally
        {
            if (originalContext != null)
            {
                originalContext.Undo();
            }
        }
    }
}

Entonces corrí estos comandos TSQL:

USE master
GO
CREATE ASYMMETRIC KEY FileUtilitiesKey FROM EXECUTABLE FILE = 'J:\FileUtilities.dll' 
CREATE LOGIN CLRLogin FROM ASYMMETRIC KEY FileUtilitiesKey 
GRANT EXTERNAL ACCESS ASSEMBLY TO CLRLogin 
ALTER DATABASE database SET TRUSTWORTHY ON;

Luego me enviaron almacenado CLR proc a mi destino la base de datos desde Visual Studio y, con ello, TSQL para ejecutar desde SSMS iniciado la sesión con la autenticación de windows:

DECLARE @i INT
--EXEC FileExists '\\\\server\\share\\folder\\file.dat', @i OUT
EXEC FileExists 'j:\\file.dat', @i OUT
SELECT @i

Si quiero hacer un archivo local o un archivo de red, siempre me sale un 0.Puedo intentar de nuevo más tarde, pero por ahora, voy a tratar de ir por un camino diferente.Si alguien tiene un poco de luz a arrojar, sería muy apreciado.

@Pablo, que el código que se ve como se debe trabajar.¿Has probado a poner un poco de seguimiento en que el método para asegurarse de que Convert.ToString(fileName) no es de alguna manera una manguera en el camino?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top