SQL游标(名为';cur#u files';的游标不存在。)

SQL游标(名为';cur#u files';的游标不存在。),sql,sql-server,Sql,Sql Server,这是我的商店程序 如果执行,为什么总是显示((一个名为“cur_files”的光标不存在。)。我忘记了这个过程中的什么 谢谢你从未声明过你的光标。我怀疑你想要类似的东西 ALTER PROCEDURE [dbo].[bulk_import_csv_from_dir] -- Add the parameters for the stored procedure here @ext varchar(10), @likefilename varcha

这是我的商店程序 如果执行,为什么总是显示((一个名为“cur_files”的光标不存在。)。我忘记了这个过程中的什么


谢谢

你从未声明过你的光标。我怀疑你想要类似的东西

 ALTER PROCEDURE [dbo].[bulk_import_csv_from_dir] 
        -- Add the parameters for the stored procedure here
        @ext varchar(10),
        @likefilename varchar(max),
        @tablename varchar(max),
        @tabeltemplate varchar(max),
        @directory varchar(8000)


    AS
    BEGIN
        --DECLARE @daily varchar(20);
        DECLARE @filename varchar(255);
        DECLARE @directory_table table (
                    id int IDENTITY(1,1)
                    ,subdirectory nvarchar(512)
                    ,depth int
                    ,isfile bit);

        SET NOCOUNT ON;
        BEGIN TRY
        -----------------------------------------------------------------

        --fill temp table with listed files
        INSERT into @directory_table (subdirectory,depth,isfile)
        EXECUTE master.sys.xp_dirtree @directory,1,1;

        --create cursor file


    execute ('IF OBJECT_ID(''cur_files'') IS NOT NULL DEALLOCATE cur_files');

        SELECT subdirectory as fname FROM @directory_table
        WHERE isfile = 1 AND RIGHT(subdirectory,4) = @ext
        AND subdirectory like @likefilename
        ORDER BY id;


        open cur_files;

        FETCH NEXT FROM cur_files 
        INTO @filename

        WHILE @@FETCH_STATUS = 0
        BEGIN


    execute ('IF OBJECT_ID('''+@tablename+''') IS NULL SELECT * INTO '+@tablename+' FROM ' + @tabeltemplate);

        declare @sql varchar(max);



    SET @sql ='BULK INSERT '+@tablename+' FROM '''+@directory+@filename+'''
   WITH (FIELDTERMINATOR = ''\n'', ROWTERMINATOR = '''+CHAR(10)+''', FIRSTROW = 3)';


        execute(@sql);

        FETCH NEXT FROM cur_files
            INTO @filename
        END

        close cur_files;
        DEALLOCATE cur_files;

        -----------------------------------------------------------------
        END TRY

        BEGIN CATCH
            SELECT 
                ERROR_NUMBER() AS ErrorNumber
                ,ERROR_SEVERITY() AS ErrorSeverity
                ,ERROR_STATE() AS ErrorState
                ,ERROR_PROCEDURE() AS ErrorProcedure
                ,ERROR_LINE() AS ErrorLine
                ,ERROR_MESSAGE() AS ErrorMessage;

            IF @@TRANCOUNT > 0
            begin
                ROLLBACK TRANSACTION;
                execute ('IF OBJECT_ID(''cur_files'') IS NOT NULL DEALLOCATE cur_files');
            end
        END CATCH;

            IF @@TRANCOUNT > 0
                COMMIT TRANSACTION;
    END

如果光标存在,我已经删除了取消分配光标的检查,因为我在声明中添加了
LOCAL
选项,它将只存在于当前作用域中,而且因为您尚未声明它,它不可能已经存在,所以这是一个冗余检查。其他选项只是为了改进内存管理,并保持cursor尽可能简单。

开始时,您正在解除分配cur_文件
光标
您没有声明cur_文件
光标
,然后,替换

--fill temp table with listed files
INSERT into @directory_table (subdirectory,depth,isfile)
EXECUTE master.sys.xp_dirtree @directory,1,1;

DECLARE cur_files CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
    SELECT  subdirectory AS fname 
    FROM    @directory_table
    WHERE   isfile = 1 
    AND     RIGHT(subdirectory,4) = @ext
    AND     subdirectory LIKE @likefilename
    ORDER BY id;

OPEN cur_files;


这里有两个主要问题。第一个问题是您没有声明游标。第二个问题是您正在使用动态sql检查游标的存在。这一行永远不会做任何事情,因为动态sql在它自己的范围内运行。这很容易证明

DECLARE cur_files CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT subdirectory as fname FROM @directory_table
WHERE isfile = 1 AND RIGHT(subdirectory,4) = @ext
AND subdirectory like @likefilename
ORDER BY id;

当您使用显式游标时,您需要先声明游标“cur_files”,然后声明游标中使用的变量,然后声明“open cur_files”。请注意,动态sql外部的解除分配不会引发异常。此外,游标不是作为系统对象创建的,因此您进行的检查首先无效。
DECLARE cur_files CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT subdirectory as fname FROM @directory_table
WHERE isfile = 1 AND RIGHT(subdirectory,4) = @ext
AND subdirectory like @likefilename
ORDER BY id;
declare cur_files cursor for select * from sys.objects

execute ('IF OBJECT_ID(''cur_files'') IS NOT NULL DEALLOCATE cur_files');

DEALLOCATE cur_files