Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加ClickHouse数据库 #943

Merged
merged 6 commits into from
Dec 3, 2021
Merged

添加ClickHouse数据库 #943

merged 6 commits into from
Dec 3, 2021

Conversation

ANCB520
Copy link
Collaborator

@ANCB520 ANCB520 commented Nov 27, 2021

添加了ClickHouse数据库支持,可以合并吗

@2881099
Copy link
Collaborator

2881099 commented Nov 27, 2021

添加了ClickHouse数据库支持,可以合并吗

谢谢贡献,近期审查合并一下,初步发现 Update 直接 Replace 的方式略显粗旷,因为有可能更新的内容也包括该内容

@ANCB520
Copy link
Collaborator Author

ANCB520 commented Nov 27, 2021

添加了ClickHouse数据库支持,可以合并吗

谢谢贡献,近期审查合并一下,发现更新直接替换的方式略显粗旷,因为有可能更新的内容也包括该内容

😊嗯嗯,想着尽量少改FreeSql源代码,外加基本不会使用到修改功能,所有...。
不过就现在还有两个已知问题还没改
一是批量添加,现在是使用的的sql字符串的方式,url会存在过长问题。
二是数据更新时,有使用到CaseWhenEnd的情况下,在数据库中字段值为NULL时,修改不会生效,ELSE必须得有值并且值不能为NULL才行

@2881099
Copy link
Collaborator

2881099 commented Dec 3, 2021

@ANCB520

1、保存数据时,数据过长问题,可以适当使用参数化。

ClickHouseUtils.cs 可以处理特殊的参数化:

        public override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, string specialParamFlag, ColumnInfo col, Type type, object value)
        {
            if (value == null) return "NULL";
            if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value);
            if (type == typeof(string))
            {
                var valueString = value as string;
                if (valueString != null)
                {
                    if (valueString.Length < 4000) return string.Concat("'", valueString.Replace("'", "''"), "'");
                    var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", null, type, value);
                    return pam.ParameterName;
                }
            }
            if (type == typeof(byte[]))
            {
                var valueBytes = value as byte[];
                if (valueBytes != null)
                {
                    if (valueBytes.Length < 4000) return $"hextoraw('{CommonUtils.BytesSqlRaw(valueBytes)}')";
                    var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", null, type, value);
                    return pam.ParameterName;
                }
            }
            return FormatSql("{0}", value, 1);
        }

以上代码大致意思:当字符串长度 >4000,或者 byte[] 类型,则强制使用参数化。

2、NULL 的问题,可能需要使用者自己注意了,NULL判断规则在许多数据库下都是这样逻辑。

@ANCB520
Copy link
Collaborator Author

ANCB520 commented Dec 3, 2021

@ANCB520

1、保存数据时,数据过长问题,可以适当使用参数化。

ClickHouseUtils.cs 可以处理特殊的参数化:

        公共 覆盖 串 GetNoneParamaterSqlValue(列表<的DbParameter > specialParams,串 specialParamFlag,ColumnInfo  COL,类型 类型,对象 值)
        {
            if ( value  ==  null )返回 “ NULL ”;
            如果(类型。IsNumberType())返回 的字符串。格式( CultureInfo . InvariantCulture , " {0} " , value );
            if ( type  ==  typeof ( string ))
            {
                var  valueString  =  value  as  string ;
                if ( valueString  !=  null )
                {
                    如果的valueString。长度 <  4000返回 字符串。Concat ( " ' " , valueString . Replace ( " ' " , " '' " ), " ' " );
                    VAR  PAM  =  AppendParamterspecialParams,$ “ P_ { specialParams ?。计数} { specialParamFlag }null ,类型,);
                    返回 帕姆。参数名称;
                }
            }
            if ( type  ==  typeof ( byte []))
            {
                var  valueBytes  =  value  as  byte [];
                if ( valueBytes  !=  null )
                {
                    如果valueBytes。长度 <  4000返回 $ “ HEXTORAW( '{ CommonUtils。BytesSqlRaw(valueBytes)}') ” ;
                    VAR  PAM  =  AppendParamter(specialParams,$ “ P_ { specialParams ?。计数} { specialParamFlag } ”,空,类型,值);
                    返回 帕姆。参数名称;
                }
            }
            返回 FormatSql(“ {0} ”,值,1);
        }

以上代码圣经英文:当字符串长度>4000,或者byte[]类型,则强制使用参数化。

2、NULL的问题,可能需要用户自己注意了,NULL判断规则在许多数据库下都是这样的逻辑。

这两个问题都已经解决了

@ANCB520
Copy link
Collaborator Author

ANCB520 commented Dec 3, 2021

只是在批量插入时,如果存在decimal类型字段,最后一位会产生精度丢失,但是这个是ado内部存在数值转换导致的,暂时没法解决

@2881099
Copy link
Collaborator

2881099 commented Dec 3, 2021

使用参数化写入 decimal 类型是否还会丢精?

        public override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, string specialParamFlag, ColumnInfo col, Type type, object value)
        {
            if (value == null) return "NULL";
            if (type.IsNumberType())
            {
                if (type == typeof(decimal))
                {
                    var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", null, type, value);
                    //pam.Precision = 10; 这两行可能需要调试
                    //pam.Scale = 2;
                    return pam.ParameterName;
                }
                return string.Format(CultureInfo.InvariantCulture, "{0}", value);
            }
            return FormatSql("{0}", value, 1);
        }

@2881099 2881099 merged commit 59f14fc into dotnetcore:master Dec 3, 2021
2881099 added a commit that referenced this pull request Dec 17, 2021
2881099 added a commit that referenced this pull request Mar 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants