使用RODBC的sqlQuery为SQL表拉出带有空格的变量

时间:2018-04-30 12:12:43

标签: sql r rodbc

在我的SQL Server数据库表中,有一个带空格的变量。我试图在public class MyClient : ServiceClient<MyClient> { public MyClient() : base(new HttpClientHandler { UseDefaultCredentials = true }) {} } 函数中编写一个查询,但我无法使用此变量。

  • 我尝试使用单引号,但这不起作用。
  • 我尝试使用ServiceClient选项并为查询创建一个字符串,但即便如此也无效。

以下是查询:

RODBC::sqlQuery

问题出现在“GBU外部细分描述”中。我收到以下错误:

  

chr [1:4]“42S22 207 [Microsoft] [ODBC SQL Server驱动程序] [SQL Server]无效的列名称”正在打印“。” ......

然后我从打印中删除了双引号但仍为“GBU外部段描述”它不接受并抛出以下错误:

  

chr [1:3]“42000 102 [Microsoft] [ODBC SQL Server驱动程序] [SQL Server]”GBU外部段描述“附近的语法不正确。” ...

2 个答案:

答案 0 :(得分:1)

错误不是我认为的字段名,而是你正在寻找的varchar常量。 你应该使用单引号,而不是双引号。

此:

a.Bus_Area_ID = b.Bus_Area_ID and b."GBU External Segment Description"= "Printing"

应该是这样的:

a.Bus_Area_ID = b.Bus_Area_ID and b.[GBU External Segment Description] = 'Printing'

通常,SQL中的字符串值不是用双引号括起来的,而是用单引号括起来的。

另外,在你的第一行:

p5 <-sqlQuery(con,'SELECT a.region,a.Country,a.Qtr_ID,Net_VAT as Variable_Type,"Printing" as [External_Segment]

您是否尝试输出 Printing 作为此查询的常量结果?如果是,并且它不是字段名称,那么您还应该将其包含在'单引号中,而不是双引号。这可能是你所看到的第一个错误的原因。

这样就变成了:

p5 <-sqlQuery(con,'SELECT a.region,a.Country,a.Qtr_ID,Net_VAT as Variable_Type,'Printing' as [External_Segment]

关于使用[]包装字段名称的问题的上一条评论是正确的,您应该使用方括号[]来包装带有空格的字段名称。

此查询应该有效:

p5 <-sqlQuery(con,'SELECT  a.region,a.Country,a.Qtr_ID,Net_VAT as Variable_Type,\'Printing\' as [External_Segment]
                          ,SUM(a.VR_Value) as Value
          from
          (SELECT  d.region,d.Country,dt.Qtr_ID
          ,sum([Actuals YTD]/1000000) as VR_Value
          FROM ZOOM_DATAMART.dbo.[New_BalSheet_Fact] a
          inner join [dbo].[Buss_Area_Dim_V] b
          on 
          a.Bus_Area_ID = b.Bus_Area_ID and b.[GBU External Segment Description]= \'Printing\'
          inner join [dbo].[BSR_Header_GA_Dim_V] c
          on
          a.BSR_HEADER_GA_KEY= c.BSR_HEADER_GA_KEY and c.[Group Account Identifier] IN (1291,2150,2151,2152,2153,2154)
          inner join [dbo].[Legal_Company_Dim_V] d
          on a.Legal_Cmp_Key = d.Legal_Cmp_Key
          inner  join dbo.Date_Dim dt
          on a.Date_key = dt.Date_key and dt.Max_month_Flag = 1
          group by d.region,
          dt.Qtr_ID
          ,d.Country
          ) a
          Group BY
          a.region
          ,a.Country
          ,a.Qtr_ID')

希望这有帮助。

答案 1 :(得分:1)

总体而言,您的主要问题涉及混淆和混淆标识符文字。作为信息,在ANSI-SQL(大多数RDBMS遵守的SQL语言的正式行业标准,包括SQL Server,Oracle,Postgres等)中,单引号和双引号用于不同的目的。 / p>

单引号用于将字符串文字括在char,varchar,文本数据类型列(如'Printing')中。您的第一条错误消息实际指向 Printing ,因为MSSQL引擎尝试搜索列名,因为您将此值包装在双引号中。

双引号用于标识符,包括列名和表名,例如c."Group Account Identifier"。您的第二个错误指​​向使用表格别名c限定为文字值,因为您将此值包装在单引号中。

以下是此类型的一些常见用法:

  • 双引号明确强加区分大小写。具体来说,当您用双引号括起列名时,camel case,lower case和upper case中的相​​同字符呈现不同的值,如果它们与表创建中使用的实际情况不对齐,则会引发错误(即{{{ 1}})。

  • 双引号有助于转义特殊字符(tbl."ColumnName" <> tbl."COLUMNNAME")和空格。因此,您可以使用!@#$%^&*?来标识列。但是,有些RDBMS对于特殊字符和空格有自己的转义符号,这些符号不是ANSI标准。例如,SQL Server可以使用方括号c."Group Account Identifier"; MySQL可以使用反引号[...]; SQLite和MS Access可以同时使用。

  • 双引号有助于转义当前RDBMS的保留字,其中包含SQL Server's list。但是,建议不要在列名中使用这些单词,特殊字符,重音符号或空格。

据说,像任何规则一样有例外。对于某些允许使用非ANSI模式的数据库,两种类型的引号可能与字符串文字一起使用。但是,建议不要这样做。与大多数编程语言(如R,Python,PHP,Perl,XSLT)不同,它们可以将这两种类型的引号换成字符串值,而基本核心的SQL不是其中之一。

因此,请相应地使用报价类型:

`...`

或者

'Printing' AS "External_Segment",
...
AND b."GBU External Segment Description" = 'Printing'
...
AND c."Group Account Identifier" IN (1291, 2150, 2151, 2152, 2153, 2154)