如何将“姓氏,名字”数据拆分为单独的姓氏和名字列?

时间:2018-12-21 20:02:18

标签: sql-server tsql coldfusion

我们有一个表,该表的列名为fullname,格式为“姓氏,名字”

我在表中添加了新列,以便我们可以区分姓氏和名字,但我不知道该如何处理。下面的代码是我使用的代码,但是“ listFirst不是公认的内置函数名称。”

<cfquery name="splitname" datasource="dsn">
UPDATE dbo.employees
SET
  lastname = listFirst(fullname, ","),
  firstname = listRest(fullname, ", ")
</cfquery>

请告知。谢谢。

5 个答案:

答案 0 :(得分:3)

一种简单的方法(这不是最好的方法。但这看起来像是一次性的事情,所以应该没问题。)是选择这些行作为单独的查询并循环更新每一行。 。另外,您需要先评估列表函数,然后再将其传递给查询。还可以使用ADJ使字符串安全进行查询。

<cfqueryparam>

答案 1 :(得分:3)

这不应该在ColdFusion中完成。这是数据问题,任何数据转换都应在SQL Server本身上进行。无需将数据拉回到CF,让CF处理数据,然后将处理后的数据传递回SQL。

正如其他评论中提到的那样,通过进行此更改,您正在打开大量意想不到的蠕虫。名称很难使用。

此答案基于以下事实:您的姓名数据由姓氏组成,后跟逗号,再由名字的其余部分组成。它将修剪名字和姓氏并删除第一个逗号,但是再次要注意Garbage In, Garbage Out.

您可以像这样将查询传递到SQL:

<cfquery name="splitname" datasource="dsn">
    UPDATE dbo.employees
    SET lastname = ltrim(rtrim(left(fullname,charindex(',',fullname+',')-1)))
      , firstname = ltrim(rtrim(substring(fullname,charindex(',',fullname+',')+1,len(fullname))))
</cfquery>

您可以在https://dbfiddle.uk/?rdbms=sqlserver_2012&fiddle=85fc8abfdbb02c469e28c2e4dd1df4f5的SQL中看到它。

答案 2 :(得分:1)

我认为您的问题是您没有将CF函数放在#号和引号中。

<cfquery name="splitname" datasource="dsn">
UPDATE dbo.employees
SET
  lastname = '#listFirst(fullname, ",")#'
  , firstname = '#listRest(fullname, ", ")#'
</cfquery>

您确实应该使用。

<cfquery name="splitname" datasource="dsn">
UPDATE dbo.employees
SET
  lastname = '<cfqueryparam cfsqltype="cf_sql_varchar" 
       value="#listFirst(fullname, ",")#">'
</cfquery>

作为最佳实践,我将在SQL语句之前清理变量,并使用trim函数消除空格。

<cfscript>
    firstname = trim(listFirst(fullname, ","));
    lastname = trim(listLast(fullname, ","));
</cfscript>

<cfquery name="splitname" datasource="dsn">
UPDATE dbo.employees
SET
  firstname = '<cfqueryparam cfsqltype="cf_sql_varchar" value="#firstname#">'
  , lastname = '<cfqueryparam cfsqltype="cf_sql_varchar" value="#firstname#">'
</cfquery>

此外,我们一直在尝试使用SQL的DECLARE语句在此处定义变量。这使得向您的DBA发出复杂的查询并使其能够快速使用它们变得非常容易。另外,许多查询多次使用相同的变量,因此在列表顶部声明它们变得更加容易和整洁。

<cfscript>
    firstname = listFirst(fullname, ",");
    lastname = listLast(fullname, ",");
</cfscript>

<cfquery name="splitname" datasource="dsn">

    DECLARE @FirstName varchar(50) = <cfqueryparam cfsqltype="cf_sql_varchar" value="#firstname#">
    DECLARE @LastName varchar(50) = <cfqueryparam cfsqltype="cf_sql_varchar" value="#lastname#">

    UPDATE dbo.employees
    SET
      firstname = @FirstName
      , lastname = @LastName

</cfquery>

答案 3 :(得分:1)

除了Shawn's answer之外,没有人提到的一件事是您可能对CF中的查询存在误解。如果不小心,可能会对数据库造成一些非常不愉快的后果。

能够混​​用CFML和SQL并不意味着您的数据库服务器执行CFML代码

数据库服务器对CFML一无所知。实际上,数据库服务器甚至根本不会在cfquery中看到 任何CFML代码。在数据库服务器甚至输入图片之前,所有CFML(和/或cfcript)代码都由CF应用程序服务器执行。

那么当您将CFML和SQL混合使用时,实际发生了什么?从概念上讲,当代码执行时:

  1. CF服务器尝试评估所有CF标签/功能,并  将它们转换为文字值。然后将这些值连接起来  与其余的纯文本SQL组成一个大的SQL字符串。

  2. CF然后将该SQL字符串交给数据库执行

  3. 数据库服务器尝试执行SQL字符串并返回任何   结果到CF服务器
  4. CF服务器将数据库结果转换为对象,例如   一个“查询”。

因此,正如您所看到的,两者绝对没有混合。 CF负责处理任何CFML。数据库处理任何SQL。从来没有吐温相遇。

潜在的问题是什么?

进行这样的查询。它不会崩溃,但也不会产生预期的结果。

<cfset FORM.newAccountNumber = "1234,ABC">

<cfquery datasource="dsn">
   UPDATE someTable
   SET    AccountNumber = '#listFirst(FORM.newValue, ",")#'
</cfquery>

这实际上是怎么回事。首先,CF执行列表函数,该函数返回文字字符串“ 1234”。

   #listFirst(variables.newValue, ",")#

CF然后将该文字插入SQL语句的其余部分,生成以下内容:

    UPDATE someTable
    SET    AccountNumber = '1234'

当发送到数据库时,该语句将整个表中的每个单个帐号设置为相同的值:“ 1234”。几乎可以肯定,这不是理想的结果。

了解查询中如何解释CFML代码可以帮助避免对数据库造成一些真正令人不愉快的后果。尤其是如果您最近没有备份...

答案 4 :(得分:0)

例如,

Listgetat可以解决问题;

listgetat(fullname,1)  
listgetat(fullname,2)