用户收到此错误
DIAGNOSTICS:执行数据库查询时出错。 [Macromedia公司] [SQLServer的 JDBC驱动程序] [SQLServer] INSERT语句中有更多列 比VALUES子句中指定的值。中的值的数量 VALUES子句必须与中指定的列数相匹配 INSERT语句。第252行发生错误。消息:错误 执行数据库查询。根本原因: coldfusion.tagext.sql.QueryTag $ DatabaseQueryException:执行错误 数据库查询。服务器:server2
应该有大约60个值/列。可能的解决方案是将<CFIF isDefined("VARIABLES.xxx")>
添加到INSERT
和VALUES
中的每个值,但这需要很长时间。有没有更好的办法?这是一些代码
<CFQUERY name="addAgency" datasource="#REQUEST.dsn#">
INSERT INTO agency (agency_name, code, address1, address2, city_id, postal, phone, alternativePhone, fax, provincialRegistration,
<!--- contact, ---> firstname, lastname, username, password, relationship_id, editdate, adddate, email, URL_link,Airport_id,
header, teaser, full_desc, <CFIF isDefined("VARIABLES.specialty")>specialty,</CFIF> hours_1, hours_2, hours_3, hours_4,
hours_5, hours_6, hours_7, merchant_ID,
region_ID, fcApproved, agencyType_ID, agencystatus, crossview, insp_Approved, rbc_Approved,
branch_number, gp_entity_ID,
<CFIF VARIABLES.alias1 gt 100> alias1,</CFIF>
<CFIF VARIABLES.alias2 gt 100> alias2,</CFIF>
<CFIF Trim(VARIABLES.alias3) NEQ ""> alias3,</CFIF>
default_agent_id,LOCAL_PASSWORD,LOCAL_USERNAME,NATIONAL_PASSWORD,NATIONAL_USERNAME,VACATIONCLUB_PASSWORD,VACATIONCLUB_USERNAME,toll_free_number,display_toll_free ,MARKETINGREGIONID, searchPreference, bookingOption,customer_can_choose
<CFIF isDefined("variables.logo_filedata")>,logo_fileName,logo_fileData,logo_mimeType</CFIF>
,gds, pseudo_city, acv_affiliate_code, vip_ext,owner_manager_title_en,owner_manager_title_fr)
VALUES (<CFQUERYPARAM value="#Trim(sanitize(VARIABLES.agency_name))#" cfsqltype = "cf_sql_varchar" maxlength="150">,
<CFQUERYPARAM value="#Trim(sanitize(VARIABLES.code))#" cfsqltype = "cf_sql_varchar" maxlength="50">,
<CFQUERYPARAM value="#Trim(sanitize(VARIABLES.address1))#" cfsqltype = "cf_sql_varchar" maxlength="255">,
<CFQUERYPARAM value="#Trim(sanitize(VARIABLES.address2))#" cfsqltype = "cf_sql_varchar" maxlength="255">,
<CFQUERYPARAM value="#sanitize(VARIABLES.city_id,true,true,false,true,false)#" cfsqltype = "cf_sql_integer">,
<CFQUERYPARAM value="#Trim(sanitize(VARIABLES.postal))#" cfsqltype = "cf_sql_varchar" maxlength="10">,
<CFQUERYPARAM value="#Trim(sanitize(VARIABLES.phone))#" cfsqltype = "cf_sql_varchar" maxlength="20">,
<CFQUERYPARAM value="#Trim(sanitize(VARIABLES.fax))#" cfsqltype = "cf_sql_varchar" maxlength="20">,
<!--- <CFIF IsDefined("VARIABLES.contact")>#Trim(VARIABLES.contact)#, <CFELSE> ' ', </CFIF> --->
<CFQUERYPARAM value="#Trim(sanitize(VARIABLES.firstname))#" cfsqltype = "cf_sql_varchar" maxlength="40">,
<CFQUERYPARAM value="#Trim(sanitize(VARIABLES.lastname))#" cfsqltype = "cf_sql_varchar" maxlength="40">,
'-', '-',
<!--- Dummy un/pw --->
<CFQUERYPARAM value="#sanitize(VARIABLES.relationship_ID,true,true,false,true,false)#" cfsqltype = "cf_sql_integer">,
#CreateODBCDateTime(Now())#,
#CreateODBCDateTime(Now())#,
<CFQUERYPARAM value="#Trim(sanitize(VARIABLES.email))#" cfsqltype = "cf_sql_varchar" maxlength="40">,
答案 0 :(得分:4)
只要您这样做,“列”区域中的每个s必须与“值”部分中的推论CFIF匹配。虽然有其他方式,但它们并不一定不那么混乱。你可以,例如:
正如你所看到的,它们都有缺点。
详细阐述1)
而不是做一些艰苦的事情,如:
<CFIF isDefined("VARIABLES.specialty")> Specialty,</cfif>
在开始查询之前,请确保使用cfparam所需的所有变量的值,如下所示:
<Cfparam name="Specialty" default=""/>
(当然,专业的默认值可能是0或其他)。
cfparam标记检查IF是否存在变量,如果不存在,则使用您指定的默认值创建它。这意味着您可以“保证”变量确实存在 - 这意味着您可以消除查询中的CFIF语句。
一个cavaet与数据库中的NULL有关。如果您依赖于空值(意味着如果不存在专业,您希望列保持为空),那么您需要将“null”属性添加到cfqueryparam中,如下所示:
<CFQUERYPARAM
value="#Trim(sanitize(VARIABLES.specialty))#"
cfsqltype = "cf_sql_varchar"
null="#mynullfunction(variables.specialty)#"/>,
注意“mynullfunction” - 我通常为此创建一个实用程序UDF,如果值为空或零(或我定义的任何内容),则返回YES,如果填充,则返回“no”。
答案 1 :(得分:1)
最好的解决方案是将cfqueryparam的null属性用于未在数据库中设置默认值的列,这意味着您可以避免向INSERT INTO添加条件并将VALUE保持为每列一行。如果列存在默认值,则需要使用long winded条件。这是最简单,最不突兀的变化。
Alias1具有数据库默认值的示例,特殊情况不是。
` <cfset Variables.IsValidAlias1 = Variables.alias1 gt 100>
<cfquery name="addAgency" datasource="#REQUEST.dsn#">
INSERT INTO agency (agency_name,
specialty
<cfif Variables.IsValidAlias1>
, Alias1
</cfif>)
VALUES (<cfqueryparam value="#Variables.agency_name#" cfsqltype="cf_sql_varchar" maxlength="150">,
<cfqueryparam value="#Variables.specialty#" cfsqltype="cf_sql_varchar" null="#StructKeyExists(Variables,'Specialty') EQ false#" maxlength="199">
<cfif Variables.IsValidAlias1>
,<cfqueryparam value="#Variables.Alias1#" cfsqltype="cf_sql_varchar" maxlength="199">
</cfif>)
</cfquery>`
顺便说一下,你应该使用StructKeyExists()而不是IsDefined,因为前者更快,读起来更清晰。您应该将此代码放在一个函数中,并将该函数放在一个组件中,以便可以重用它。这是假设您使用CF6或更高版本。
答案 2 :(得分:0)
我会避免为每个字段设置空字符串默认值,或者为不存在的键设置值为NULL。原因是您现在可能(或决定将来)数据库列中的默认值。由于生成的NULL值是显式的,它们将覆盖您的数据库默认值。如果您传入了一个空字符串,这可能是有效的,但默认情况下可能不是。
我的主要建议是将每一栏保持在一行,以便您可以轻松地看到您的条件一致。正如马克所说,你必须小心在“列”区域中拥有与查询的“值”区域完全相同的条件。
除此之外,我有一个名为DataMgr的免费工具,您可以使用它来管理大多数简单查询的所有这些事情。
http://www.bryantwebconsulting.com/docs/datamgr/replace-sql-inserts-and-updates.cfm http://www.bryantwebconsulting.com/docs/datamgr/getting-started.cfm
然而,最重要的是要保持条件的一致性并格式化查询,以便在不存在时使其显而易见。