При массовой загрузке из файла возникла ошибка. Невозможно выполнить массовую загрузку, поскольку файл не может быть открыт - PullRequest
0 голосов
/ 15 мая 2018

Я работаю с удаленным Microsoft SQL Server.

После выполнения следующего кода с использованием DataGrip в Ubuntu я получаю сообщение об ошибке:

CREATE TABLE #TempNullClass (
  id          nvarchar(10),
  classCode   nvarchar(10)
);

BULK INSERT #TempNullClass
FROM '/home/user/Downloads/data1.csv'
  WITH (
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = '0x0a'
  );

[S0001] [4861] Невозможно выполнить массовую загрузку, поскольку файл "/home/user/Downloads/data1.csv" не может быть открыт. Код ошибки операционной системы 3 (система не может найти указанный путь.).

Файл имеет все разрешения:

-rwxrwxrwx 1 user user      73399 may 15 15:11 data1.csv

Я не могу поместить файл на удаленный сервер.

Ответы [ 2 ]

0 голосов

Вы можете использовать локальный файл, путь к файлу должен быть относительно сервера, поэтому файл на другом компьютере должен быть UNC-путем, локальный путь к серверу не должен бытьподелиться (проблема безопасности и еще одна вещь, которую вам нужно настроить и контролировать).

Мне иногда приходится перебирать импортные файлы, как это делают все другие администраторы баз данных.Я решаю это такВы можете сбросить его в задании SQL и запланировать его.Может работать каждую секунду или каждый день, зависит только от ваших бизнес-требований.Вот пример одного из моих сценариев:

SET NOCOUNT ON

DECLARE @BackupDirectory SYSNAME = 'G:\'

  IF OBJECT_ID('tempdb..#DirTree') IS NOT NULL
    DROP TABLE #DirTree

  CREATE TABLE #DirTree (
    Id int identity(1,1),
    SubDirectory nvarchar(255),
    Depth smallint,
    FileFlag bit,
    ParentDirectoryID int
   )

   INSERT INTO #DirTree (SubDirectory, Depth, FileFlag)
   EXEC master..xp_dirtree @BackupDirectory, 10, 1


   UPDATE #DirTree
   SET ParentDirectoryID = (
    SELECT MAX(Id) FROM #DirTree d2
    WHERE Depth = d.Depth - 1 AND d2.Id < d.Id
   )
   FROM #DirTree d

  DECLARE 
    @ID INT,
    @BackupFile VARCHAR(MAX),
    @Depth TINYINT,
    @FileFlag BIT,
    @ParentDirectoryID INT,
    @wkSubParentDirectoryID INT,
    @wkSubDirectory VARCHAR(MAX)

  if OBJECT_ID('dbo.ImportFiles')=0
  create table dbo.ImportFiles
  (
    FileNamePath VARCHAR(MAX)
  )
  else
    truncate table dbo.ImportFiles


  DECLARE FileCursor CURSOR LOCAL FORWARD_ONLY FOR
  SELECT * FROM #DirTree WHERE FileFlag = 1

  OPEN FileCursor
  FETCH NEXT FROM FileCursor INTO 
    @ID,
    @BackupFile,
    @Depth,
    @FileFlag,
    @ParentDirectoryID  

  SET @wkSubParentDirectoryID = @ParentDirectoryID

  WHILE @@FETCH_STATUS = 0
  BEGIN
    --loop to generate path in reverse, starting with backup file then prefixing subfolders in a loop
    WHILE @wkSubParentDirectoryID IS NOT NULL
    BEGIN
      SELECT @wkSubDirectory = SubDirectory, @wkSubParentDirectoryID = ParentDirectoryID 
      FROM #DirTree 
      WHERE ID = @wkSubParentDirectoryID

      SELECT @BackupFile = @wkSubDirectory + '\' + @BackupFile
    END

    --no more subfolders in loop so now prefix the root backup folder
    SELECT @BackupFile = @BackupDirectory + @BackupFile

    INSERT INTO ImportFiles (FileNamePath) VALUES(@BackupFile)

    FETCH NEXT FROM FileCursor INTO 
      @ID,
      @BackupFile,
      @Depth,
      @FileFlag,
      @ParentDirectoryID 

    SET @wkSubParentDirectoryID = @ParentDirectoryID      
  END

  CLOSE FileCursor
  DEALLOCATE FileCursor

SET NOCOUNT ON
print 'loading files from file table'
-- =============================================
-- Declare and using a READ_ONLY cursor
-- =============================================
DECLARE eoddata_cursor CURSOR
READ_ONLY
FOR SELECT FileNamePath FROM ImportFiles
    where FileNamePath like '%.csv'

DECLARE @name nvarchar(4000), @sql nvarchar(2000), @rows int
OPEN eoddata_cursor

FETCH NEXT FROM eoddata_cursor INTO @name
WHILE (@@fetch_status <> -1)
BEGIN
    IF (@@fetch_status <> -2)
    BEGIN       
        print 'file '+@name
        begin try

            truncate table [Tickers].[DataClient]

            set @sql = '
            bulk insert [Tickers].[DataClient]
            from N'''+@name+'''
            with (
              FIELDTERMINATOR ='','',  
              ROWTERMINATOR =''\n'' ,
              FIRSTROW = 2,
              CODEPAGE = ''RAW'',
              MAXERRORS = 2000000,
              ERRORFILE = '''+@name+'.err''
            )'


            insert into [Tickers].[DataClient]


            exec(@sql)

            exec [Tickers].[MoveDataClientData] @filename = @name, @rows = @rows output

            delete from ImportFiles where FileNamePath = @name
            print 'loaded :'+str(@rows)
        end try
        begin catch
            print 'error:'+ error_message()

        end catch


    END
    FETCH NEXT FROM eoddata_cursor INTO @name
END

CLOSE eoddata_cursor
DEALLOCATE eoddata_cursor
GO
0 голосов
/ 15 мая 2018

Файл должен быть размещен на удаленном сервере или в папке, к которой открыт общий доступ для удаленного сервера.

...