Ошибка программирования: ('42000', "[42000] [Microsoft] [Драйвер ODBC 13 для SQL Server] [SQL Server] Неверный синтаксис рядом с '@ P1'. (102) - PullRequest
0 голосов
/ 20 октября 2019

Вот мой код. Я получаю сообщение об ошибке в инструкции BULK INSERT. Скажите, пожалуйста, почему массовая вставка не работает:

local_path="C:\\Users\\sankalp.patil\\assignment\\upload" 

block_blob_service = BlockBlobService(account_name='samplsa', account_key='+M5icqu9BNzqTMfYMsYhFEROBjdgFHMIyYytsbBRqATVllUP0XyHcsgbxGmEC4zu0QtpW7rAn2Vf4PsBMVa5eg==')
container_name = 'targetcontainer'
block_blob_service.create_container(container_name)

for files in os.listdir(local_path): block_blob_service.create_blob_from_path(container_name,files,os.path.join(local_path,files))

server = 'sample-server1.database.windows.net'    
database = 'targetdb'    
username = 'sankalp'    
password = 'mypassword'    
driver= '{ODBC Driver 13 for SQL Server}'
def sqlconnect(server,database,username,password):
    try:
        return pyodbc.connect('DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password)
    except:
    print ("connection failed check authorization parameters")  
conn = sqlconnect(server,database,username,password)
cursor = conn.cursor()


for files in os.listdir(local_path):
    path=os.path.join(local_path,files)
    filename=(os.path.splitext(files)[0])
    tablename = 'dbo.'+filename
    print(files)
    print(path)
    print(tablename)
    sql = "BULK INSERT ? FROM ? WITH (DATA_SOURCE = 'j',FIELDTERMINATOR=',',ROWTERMINATOR='\n')", tablename , files
cursor.execute(*sql)

conn.commit()
cursor.close()
print("Done")
conn.close()




I have created a data source in azure sql db as follows :

create external data source j
    with(
        type = BLOB_STORAGE,
        location = 'https://samplsa.blob.core.windows.net/targetcontainer'
        )

Итак, я копирую файлы из моей системы в хранилище BLOB-объектов Azure, а затем пытаюсь скопировать файлы из BLOB-объектов в базу данных SQL Server Azure. Но я получаюошибка как

Ошибка:

[42000] [Microsoft] [Драйвер ODBC 13 для SQL Server] [SQL Server]
Неверный синтаксис рядом с '@ P1'
(102) (SQLExecDirectW);[42000] [Microsoft] [Драйвер ODBC 13 для SQL Server] [SQL Server] Оператор (ы) не может быть подготовлен. (8180)

1 Ответ

0 голосов
/ 20 октября 2019

Как я уже упоминал в комментарии, вы не можете параметризировать имена объектов или часть кода, который должен быть литералом. Например, что-то вроде приведенного ниже не будет работать:

DECLARE @TableName sysname;
SET @TableName = N'MyTable'

SELECT *
FROM @TableName;

Вы получите сообщение о том, что переменная таблицы @TableName не была объявлена.

Поэтому вам нужноиспользовать динамический SQL и безопасно ввести значения в строку. Я не знаю Python, но я подозреваю это будет работать:

sql = "DECLARE @SQL nvarchar(MAX) = N'BULK INSERT ' + QUOTENAME(?) + N' FROM N' + REPLACE(?,'''','''''') + N' WITH (DATA_SOURCE = ''j'',FIELDTERMINATOR='','',ROWTERMINATOR=''\n'');'; EXEC sp_executesql @SQL;", tablename , files

Причина, по которой я использую REPLACE в пути к файлу, заключается в том, что тип данных первого параметра QUOTENAMEравен sysname (фактически nvarchar(128) NOT NULL), а путь к файлу может быть длиннее 128 символов. Таким образом, QUOTENAME может усечь значение;поэтому я использовал REPLACE вместо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...