【问题标题】:How to change number formatting for Hana SQL query session or connection?如何更改 Hana SQL 查询会话或连接的数字格式?
【发布时间】:2025-11-22 11:35:01
【问题描述】:

对于将 SAPB1 与 HanaDB 结合使用的客户,我们执行相同的查询以提取数据(使用 ADO.NET 接口)。有些有他们的区域系统系统,这些系统似乎可以根据他们的语言环境等控制数字格式。

例如执行时说:SELECT RDR1."Quantity" FROM RDR1

  • 对于美国的客户,RDR1."Quantity" = 2.000000
  • 对于德国的客户,RDR1."Quantity" = 2,000000(注意逗号与小数)

我假设该值的实际数据库存储是相同的,只是查询引擎根据设置应用默认系统格式,使最终结果以一种或另一种方式格式化。

现在,可以使用蛮力方法对每列进行这种类型的更改: REPLACE(CAST(ROUND(RDR1."Quantity",2) AS DECIMAL(10,2)), ',', '.') AS "Quantity” 给我“2.00”

但是,我们有很多这样的列,我们希望使代码在所有情况下都可用,而不是为不同区域提供相同查询的多个实例——而且似乎应该有一种方法来告诉查询引擎返回值,就好像它在美国一样,并忽略默认的系统区域设置和货币设置。

问题:是否可以进行高级设置更改而不是按列格式化/转换 - 使用 Hana SQL 查询代码(如会话变量或其他东西)或连接设置,当我们建立与 HanaDB 的 ADO.NET 连接,这将使值像在美国一样出现?

我还没有找到任何东西,但在如何处理它的文档中可能不太容易找到。

【问题讨论】:

    标签: hana sapb1 hana-sql-script


    【解决方案1】:

    不,没有 HANA 设置可以定义应用程序(在您的情况下为 SAP Business One)如何将数据呈现到用户屏幕。

    对于 SAP B1,您可以找到用于设置这些用户设置的文档here。 这些设置包括“千位分隔符”、“分隔符”、“小数位”等。

    但在 HANA 数据库级别,没有全局设置。

    此外,提到的REPLACE 解决方法将输入数字数据转换为字符串,从而丢失所有数字语义(排序、数学运算)并增加这些值的内存需求。 如果可能,请尽量避免使用这种技术。

    【讨论】:

    • 您好 Lars,感谢您的意见。我们直接使用 HanaDB 执行,我们不与 B1 交互。如果您建议在查询中避免使用“REPLACE”这种技术,那么如果使用查询数据输出的客户端应用程序希望使用基于美国设置的数字格式的数据,您会推荐哪种技术?此外,您认为控制此数字行为的设置是在 HanaDB(或运行它的服务器)上还是在运行 .NET 应用程序的服务器上,以及我们是否能够更改运行应用程序的计算机的设置会有影响吗?
    • Lars,在重新阅读您的帖子后,我想我看到您可能已经将解决​​方法解释为更改 HanaDB 中数据的一种方式 - 它不是。更改数据只是一种解决方法,因为它通过 TAB 分隔的文本文件从查询输出到客户端应用程序,在该文件中将被读回,字符串化的十进制将转换为实际的十进制。它作为字符串的生命在输出时只是短暂的。
    • 我建议您更改正在使用的任何客户端应用程序的显示设置。再说一遍:没有“服务器端”设置。请查看您对用户区域设置的理解。
    • Lars,我非常了解区域设置。正是这些设置必须导致输出成为它的样子。我们的客户端应用程序没有显示,除了数据库用户之外没有“用户”可以连接,它只是将数据从 HanaDB(通过 ADO.NET 连接)导出到客户环境中计算机上的本地文本文件。如果您在文本编辑器中打开该文件,您可以清楚地看到它具有特定于语言环境的格式。如果用户是指操作系统用户,是的 - 我们无法为客户更改这一点,我认为这会影响 HanaDB 引擎或 .NET 应用程序
    • 为了澄清和简化我上面的评论(我现在无法编辑),我们的客户端应用程序是一个控制台应用程序(无显示),它只是通过 ADO.NET 连接执行查询并编写输出到文本文件。在 HanaDB 和将输出写入文件之间的某个地方,必须涉及两台计算机之一上的语言环境设置,这一点很清楚。问题一写出来就在文本文件中可见。
    【解决方案2】:

    如果你想改变程序输出的小数点分隔符,只需告诉 .NET。 一个选项是在这个 sn-p 中设置当前线程的文化:

    using System;
    using System.Globalization;
    
    class Program
    {
        static void Main(string[] args)
        {
            decimal d = 2021.1002m;
            
            Console.WriteLine("Current Culture is {0}.", System.Threading.Thread.CurrentThread.CurrentCulture.Name);
            Console.WriteLine("d = {0}.", d);
            
            System.Threading.Thread.CurrentThread.CurrentCulture =
                new CultureInfo("en-US");
                
            Console.WriteLine("Current Culture now is {0}.", System.Threading.Thread.CurrentThread.CurrentCulture.Name);
            Console.WriteLine("And d = {0}.", d);
        }
    }
    

    对我来说,输出是:

    Current Culture is es-ES.
    d = 2021,1002.
    Current Culture now is en-US.
    And d = 2021.1002.
    

    【讨论】: