这是我的代码。我在"批量插入"语句中收到错误。请说明批量插入不起作用的原因:
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'
)
所以我正在将文件从我的系统复制到 azure blob 存储。然后尝试将文件从 blob 复制到 azure sql 数据库。但是我收到错误
错误:
[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]'
@P1'(
102( (SQLExecDirectW( 附近的语法不正确;[42000] [Microsoft][ODBC 驱动程序 13 SQL Server][SQL Server]无法准备语句。(8180(
正如我在注释中提到的,您不能参数化对象名称或需要成为文字的代码的一部分。例如,如下所示的内容将不起作用:
DECLARE @TableName sysname;
SET @TableName = N'MyTable'
SELECT *
FROM @TableName;
您会收到一个错误,指出尚未声明 Table 变量@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
。