我有一些文本文件,我必须在SQL的一个表中插入。我有单独的表,其中存储了我的文本文件名。我必须从该表中获取名称,然后使用fileOpen()
从特定文件夹中获取文件。在我完成该步骤之后,我有问题来决定进行后续步骤的最佳方法是什么。所以我必须使用fileReadLine()
来获取每个文本文件行的上下文。此外,我不应该读第一行,因为它只包含列名。其次,我必须检查一旦我到达文件的末尾。最后,我必须循环并将INSERT插入表中。我想知道有没有新方法这样做?我当前的代码有两个cfloops
,看起来非常低效。这是我目前的代码:
<!--- Grab stuff from File Table. --->
<cfquery datasource="test" name="myQuery1">
SELECT *
FROM FilesTxt
</cfquery>
<cfloop query="myQuery1">
<!--- Read File --->
<cfset dataFile = fileOpen(here is my path&"\"&#FileName#, "read" ) />
<cfset line = fileReadLine( dataFile ) />
<!--- Loop to see if hit the end of file, if not, read next line --->
<cfloop condition="!fileIsEOF( dataFile )">
<cfset line = fileReadLine( dataFile ) />
<cfif trim(line) NEQ "">
<cfset line = #Replace(line,"'","","ALL")#>
<cfset line = #Replace(line,'"',"","ALL")#>
<!--- Build array of junk in the file --->
<cfset sList = ListToArray(line, chr(9),'yes')>
<cftry>
<cfquery datasource="test" name="Insert">
//Here is my Insert statement
</cfquery>
</cftry>
</cfif>
</cfloop>
</cfloop>
我正在考虑做一个单独的循环,它将创建包含应插入的所有元素的数组,然后运行另一个循环来执行插入。我不确定在这种情况下最好的方法是什么。如果有人知道其他任何方式,请告诉我。感谢
答案 0 :(得分:2)
您可以直接循环文件行:
<cfloop file="**path/filename**" index="LineOfMyFile">
<cfoutput>#LineOfMyFile#</cfoutput>
</cfloop>
循环终止于文件末尾,因此您不需要fileisEOF()函数。
在循环中,您可以使用列表函数而不是循环遍历数组。如果您知道列表中项目的位置。像这样:
<cfloop file="**path/filename**" index="LineOfMyFile">
<cfquery name="myinsert" datasource="#blah#">
INSERT INTO myTable (col1, col2, col3)
VALUES (<cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#listgetat(lineOfMyFile,1,char(9))#">,
<cfqueryparam cfsqltype="CF_SQL_CHAR" value="#listgetat(lineofmyFile,2,char(9))#">,
<cfqueryparam cfsqltype="CF_SQL_CHAR" value="#listgetat(lineofMyFile,3,char(9))#">)
</cfquery>
</cfloop>
这将是一个循环。根据文件的大小,它可能会更高效,也可能不会更高效。此外,通常会检查类型,null,空字符串 - 类似的东西。因此,在插入之前,您可能会有一些数据按摩代码。希望这会有所帮助。
答案 1 :(得分:1)
如果要在表中插入100,000个值,则无法生成100,000个INSERT语句。
专业的数据库专有工具或命令可以以更优化的方式完成,但我个人认为嵌套循环并没有太大的错误。
<cfquery name="files" datasource="test">
SELECT FileName FROM FilesTxt
</cfquery>
<cfloop query="files">
<cfset file = fileOpen("here is my path\#FileName#", "read")>
<cfset fileReadLine(file)>
<cfloop condition="not fileIsEOF(file)">
<cfloop list="#fileReadLine(file)#" delimiters="#Chr(9)#" index="item">
<cftry>
<cfquery datasource="test">
INSERT testTable (testColumn) VALUES (
<cfqueryparam value="#Trim(item)#" cfsqltype="CF_SQL_VARCHAR">
)
</cfquery>
</cftry>
</cfloop>
</cfloop>
</cfloop>
注意:
SELECT *
。为您需要的列命名。files
比myQuery1
好得多。除非要将变量内容插入字符串,CF标记属性或输出中,否则无需使用##
。
<cfset line = #Replace(...)#> <!--- useless use of ## --->
<cfset line = Replace(...)> <!--- much better --->
您可以使用<cfloop list="">
循环CSV文件中的一行。毕竟,这是一个简单的清单。
<cfqueryparam>
。这样您就不必担心值中的引号。它在循环中也更有效。name
<cftry>
没有<cfcatch>
,除非您确实不关心错误。答案 2 :(得分:-2)
所有这些答案都是错误的。如果要插入一堆值,请使用SQL BULK INSERT
<cfset myInserts = "">
<cfloop file="test" index = "line">
<cfset myInserts = listAppend(myInserts,"(#line#)">
</cfloop>
<cfquery>
INSERT INTO myTable VALUES #preserveSingelQuotes(myInserts)#
</cfquery>