Infor ERP LN的数据表里的两个隐藏字段:T$REFCNTD和T$REFCNTU

拿Item General Data的Table – tcibd001举例,如果你在数据库里直接查询,你会看到两个字段:T$REFCNTD和T$REFCNTU,图示如下:

但是,如果从LN里面的ttaad4500看表结构,你是看不到的。

这两个字段有什么用呢?

refcntd – Referential Control Delete Mode
refcntu – Referential Control Update Mode

字段Refcntd存储一条记录的删除约束的数量
字段Refcntu存储一条记录的更新约束的数量。
只要通过Tools模块新增的表,这两个字段会自动添加到每个Baan/LN表中,您不必手动添加它们。

以下来自官方的介绍:

To guarantee referential integrity, the Baan/LN Database stores reference counters, which indicate how many times a record is used in a parent child relation. Since baan/LN can store each data in a several different database, we can not use the referential integrity mechanisms of the database itself. The field Refcntd stores the number of delete constraints to a record, the Refcntu stores the number of update constraints to a record. These fields are automatically added to each Baan table so you do not have to add them manually.

Only if the reference counter is zero, can the parent record be deleted.
Reference counters are only applicable if the Referential Control Delete Mode (refcntd) or Referential Control Update Mode (refcntu) in the relation is “Restricted (with counter)”.

为什么要说这个呢

重点来了,有时候,你需要从外部程序往Baan/LN的表写记录,那么就得考虑给这两个字段赋值的问题了。

别忘了在你的语句中增加这两个字段,比如:(T$REFCNTD,T$REFCNTU) VALUES (0,0)

至于为啥赋值为零,我这个新表其实没啥关联的表,那么都默认为0了。

好了,春节将至,特以此文收官祝广大Infor ERP LN/Baan战友们2021牛年大吉大利、身体健康、万事如意!

#0012:憋了一年多的盘点App小工具,还是公开吧

这个系列文章的上一篇#0011距离今天1年零2个多月,期间多次想写这个从2019年10月28日开始的众筹项目:盘点Apphttps://pandianapp.com/,都忍住没公开。

目前年底仓库大盘点的越来越多,经过1年多打磨的产品,虽然比互联网大厂的水准差些,但都是用心之作,既然可以帮到更多的企业,没什么好怕的,厚着脸皮也要给大家推荐、给有需要的公司推荐。没有经费做付费宣传曝光,先从自己的博客开始推广吧。

这个项目的缘起其实挺有趣,这个故事我想下次单独写,今天先用倒叙的方式来做个开端。

想听故事的,记得下周回来看。

今天就请先记住广告语:今年仓库年终大盘点,想要快、准、省,就用盘点App仓库版。

好像有些啰嗦,请懂行的、专业的读者您帮我优化下。

别忘了留言给我,先谢了!

Web管理端网址

https://web.pandianapp.com

最后附上App下载二维码

上厕所的时候看到的一个超级赞的东东#1

上厕所是一个特别的场景,有时候总会遇到有趣的事情,所以开了这个系列记载。

当然了,因为上厕所一篇时间较短,所以每一篇都是短篇。

今天分享的是在一家日企的厕所看到的一个流程图,第一次看到这个介绍,我被惊讶到了。

作为一个自称BPM(业务流程管理)专家的我,直呼汗颜,茅塞顿开!

我觉得这个流程写得有几个亮点:

1、工具配图
2、位置配图
3、错误和正确的参考图
4、简洁精炼的文字介绍

给我最大的其它的是,把工具用ABC的英文来命名,对位置用123数字命名。这其实对于我们常规的流程梳理,两个维度就可以用英文、数字来清晰地区分。如果还有多个维度,还可以使用中文的甲乙丙丁或者中文的壹贰叁肆。这个做法简直太妙了!

Infor ERP LN有用的Session:ttstpdeldeflt Remove User Defaults

在使用Infor ERP LN的过程中,由于网络中断或者不稳定经常会出现用户打开某个Session的时候报错,信息类似如下:

Fatal error : value DsNheight=-280 out of range

那么这时候,用户怎么也打不开想要使用的Session了,这时候就需要用到这个有用的Session:Remove User Defaults.

输入用户的账号,选择相应的公司,然后输入对应的Session Code,点击Remove即可。

宝塔LNMP环境WordPress二级目录伪静态的设置

我这个站的WordPress位于主域名下的/shanghai/下面,原来国外主机用的Apache,现在这个是Nginx主机,所以伪静态的规则要重新改下。

宝塔可以很方便生成WordPress的顶级目录下的伪静态代码,但对于二级目录就的自己写了。

代码如下,把其中的/shanghai/改为你的目录即可。

location /
{
	 try_files $uri $uri/ /index.php?$args;
}

rewrite /wp-admin$ $scheme://$host$uri/ permanent;

location /shanghai/ {
index index.html index.php;
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /shanghai/index.php;
}
}

国内主机请关闭WordPress自动更新

如果你部署在国内,你就知道升级的时候会不断地遇到升级失败,然后整站就不能访问了。

原因及重要性不必多说,那就说说关闭的方法吧:配置wp-config.php文件

全局配置文件wp-config.php位于wordpress程序根目录下的,在文件最后加入如下代码:

/** 关闭WordPress自动更新升级 */
define('AUTOMATIC_UPDATER_DISABLED', true);

经历了WordPress被种木马,回到国内(上海)主机

11月17日,Tony微信告诉我博客不能访问了,我一看被植入了js木马。

回想了一下11月4日还写博客来的,当时没有什么问题的。

赶紧问服务商有没有备份,最近的备份是哪天的?得到的答复是只保留最近3天的备份,找到最早的是11月14日的,可惜那时候已经被黑了。数据库和程序都被动了。

看了一下本地的备份,最近的是3月份的,也就是说半年多的博客要丢了。

头大,但工作挺忙,也顾不上了。

第一个念头就是,搬回阿里云,只要有付费的每日备份。

碰到青云有个双十一的活动,就随手买了个Linux的上海主机。正好也需要备案,就没急着捣鼓。等到了周末暂时利用新主机上的MySQL数据,看了一下被植木马的数据库,发现规律就是每篇文章都在结尾加入了一串javascript代码,同时站点的home和site的配置项都被改为木马的网址。

于是心里一喜,果断的写了REPLACE替换,清除了木马。

此时有了信心,拿起我的BeyondCompare文件比较利器,对WordPress程序与原版程序作了对比,发现不少上传的php文件,还有无后缀的木马文件。同时发现了被修改的程序文件,就这样逐渐的把程序的木马也清理了。

此时备案还在进行中,就在原来的国外主机上进行了程序和数据库的覆盖,当然了本地也保存了备份。

果然,网站正常了。欣喜的告诉小伙伴们,大家非常期待我分享如何清除木马的。

我还是比较谦虚的,希望等几天看看,是否还有未清理的木马,不然分享就是给自己丢人。

果不其然,替换后的第二天,程序又被植入了木马。

干净对虚拟机下的其他站点目录都进行了清理,还删除了几个漏网之鱼。

这下基本上放心了,此时备案也快完成了。

于是在新主机上玩BT宝塔,对服务器安全、网站目录、端口放行、SSL证书、WordPress二级目录下的伪静态等全部研究了一遍。

昨天,改了DNS,指向到了新主机。

老主机的数据全部删除了,希望在新主机上,在宝塔的协助下,能够安全不被黑。

这篇作为流水账,下次分享详细的木马清理过程,还有WordPress文件目录安全设置和伪静态的相关内容。

.NET程序连接Oracle一次执行多行SQL的注意事项

以前写的基于MSSQL数据库的.NET程序,不用担心SQL语句中的;或者换行符。但是因为要基于Infor LN的Oracle数据库进行开发,就碰到了;分号和换行的报错,同时一次执行UPDATE的多条更新语句时,也会报错。

Oracle.ManagedDataAccess.Client.OracleException:ORA-00911: invalid character

单行SQL如果有换行时,加了;就报上面的错,多行执行的时候,会报下面这种错误

Oracle.ManagedDataAccess.Client.OracleException:ORA-06550: line 1, column 1:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:

   ; <an identifier> <a double-quoted delimited-identifier>
The symbol ";" was substituted for "end-of-file" to continue.

虽然从网上能搜索到ExecuteNonQuery执行Oracle多条SQL的时候需要用到以下结构

BEGIN
SQL1;
SQL2;
SQL3;
END;

但是并没有人提到一定要确保整个SQL是一行,必须没有换行!

BEGIN
 UPDATE BAANDB.TWHINH225301 A
 SET A.T$WVID = -999
,A.T$ASGN = 1
,A.T$PKID = 'Troy'
,A.T$STLO = 'EMS'
 WHERE A.T$RUNN = 'CN432789'
 AND A.T$PICM = 1
 AND A.T$ASGN = 2
 AND A.T$PCKD = 2;
UPDATE BAANDB.TWHINH225301 A
 SET A.T$WVID = -999
,A.T$ASGN = 1
,A.T$PKID = 'Troy'
,A.T$STLO = 'EMS'
 WHERE A.T$RUNN = 'CN432785'
 AND A.T$PICM = 6
 AND A.T$ASGN = 2
 AND A.T$PCKD = 2;
END;

因为写日志看SQL方便,用了AppendLine,那么下面的代码中,需要手动替换下换行符:Replace(Environment.NewLine, ” “),如果还不放心,可以用Replace(“r\n”, ” “).Replace(‘\n’, ‘ ‘).Replace(‘\r’, ‘ ‘) 批量将各种换行符替换为空格。

            var result = 1;
            var sb = new StringBuilder();
            sb.AppendLine("BEGIN");
            foreach (var entity in list)
            {
                sb.AppendLine("UPDATE BAANDB.TWHINH225" + companyId + " A");
                sb.AppendLine("SET A.T$WVID = -999");
                sb.AppendLine(",A.T$ASGN = 1");
                if (!string.IsNullOrEmpty(entity.Picker))
                {
                    entity.Picker = dbHelper.SqlSafe(entity.Picker);
                    sb.AppendLine(",A.T$PKID = '" + entity.Picker + "'");
                }
                if (!string.IsNullOrEmpty(entity.StagingLocation))
                {
                    entity.StagingLocation = dbHelper.SqlSafe(entity.StagingLocation);
                    sb.AppendLine(",A.T$STLO = '" + entity.StagingLocation + "'");
                }
                // By Line
                sb.AppendLine("WHERE A.T$OORG = " + GetOrderOrigin(entity.OrderOrigin));
                sb.AppendLine("AND A.T$ORNO = '" + entity.OrderNumber + "'");
                sb.AppendLine("AND A.T$OSET = " + entity.OrderSet);
                sb.AppendLine("AND A.T$PONO = " + entity.Line);
                sb.AppendLine("AND A.T$SEQN = " + entity.SequenceNumber);
                sb.AppendLine("AND A.T$SERN = " + entity.Advice);
                // Check Assign Status
                sb.AppendLine("AND A.T$ASGN = 2");
                sb.AppendLine("AND A.T$PCKD = 2;");
            }
            sb.AppendLine("END;");
            try
            {
                ExecuteNonQuery(sb.ToString().Replace(Environment.NewLine, " "));
            }
            catch (Exception e)
            {
                LogUtil.WriteException(e);
                result = 0;
            }

            return result;

因为这个问题,还从大石头的新生命微信群发了红包求助,意外收获了结识了一个挺不错的开发者王振(王Bank)和他写的DbHelper:https://gitee.com/wangbank/BankDbHelper

.NET程序中如何解决Google Chrome浏览器iframe禁止跨域的SameSite的Cookie设置

这个问题是我们总部的一个外部应用,给到我们的客户每家一个iframe的嵌套页面,通过计算handshake的动态值,实现免登录的。这其中用到了Cookie和服务器端的Form认证。

伴随着谷歌浏览器(80版本之后对cookie的校验更加严格,SameSite属性默认值由None变为Lax)的升级,iframe中的Cookie跨域被默认禁用了,除非SameSite为None并Secure属性为True(强制SSL启用HTTPS访问)

经过印度第三方外包公司45天的调查处理,仍未解决。

经过远程会议,了解了现在团队已经做过的尝试,大的方向没错,目前未能解决的问题是

无法将2个Cookie的SameSite写成None

.ASPXAUTH
ASP.NET_SessionId

一开始我以为改用最原始的HTTPCookie的方式写就行了,但是这两个Cookie就是无法赋值。微软官网建议的在Web.config和Global.asax设置也没用。

好在透过Google看到有人提到用URL Rewrite工具,果然有效。

最终解决方案,用URL重写工具,在system.webServer节点写入Outbound规则如下:

    <rewrite>
      <outboundRules>
        <rule name="AddSameSiteCookieFlag">
          <match serverVariable="RESPONSE_Set-Cookie" pattern="^(.*)(ASP.NET|ASPXAUTH|SessionId)(=.*)$" />
          <action type="Rewrite" value="{R:0};SameSite=None" />
        </rule>
      </outboundRules>
    </rewrite>

而原有的<forms />认证信息中,必须加入requireSSL=”true”,总共涉及9行代码。

最终印度第三方外包公司的同事高高兴兴的去部署到服务器了。

BPM一夜之间都成了低代码开发平台

月初中国软件网的记者赵满满筹备一篇BPM的文章,微信联系到我问几个问题,让我重新去关注了一下当下国产BPM的一些现状。

最大的发现是:一夜之间,你去国内的BPM厂商的官网去看,每家都增加了低代码平台的宣传口号。

我搜集整理了一下,比方第一家易正的新口号:Low-Code,流程快速开发平台

奥哲的新口号:低代码开发平台云产品与方案提供商

炎黄盈动的新口号:全球领先的低代码和BPM PaaS服务商

没想到这两年低代码平台的崛起对周边产品的影响这么大,很多时候一个概念出来的时候,边界很难限定,影响也很难预估。

最后附上中国软件网的《低代码、中台化、AI化并发,BPM会成为大赢家?》文章链接。