91 lines
4.1 KiB
Markdown
91 lines
4.1 KiB
Markdown
![]() |
# 问题情况
|
|||
|
|
|||
|
在定义对象分类的 **常规属性界面** 时,保存失败,提示将截断字符串或二进制数据
|
|||
|
|
|||
|

|
|||
|
|
|||
|
尽管没办法保存,但可以先在 **常规属性页面** 右键选择 **保存到磁盘**,先将定义好的页面保存下来,待处理完问题后,再通过 **从磁盘加载** 选项进行恢复
|
|||
|
|
|||
|

|
|||
|
|
|||
|
# 解决方法
|
|||
|
|
|||
|
打开服务器,找到三品PLM服务端的安装位置,打开`log`文件夹,找出对应日期的以`sql`开头的日志文件
|
|||
|
|
|||
|

|
|||
|
|
|||
|
将其打开后,搜索“截断”二字
|
|||
|
|
|||
|

|
|||
|
|
|||
|
将这一整行的内容全部复制出来(非常非常多)
|
|||
|
|
|||
|

|
|||
|
|
|||
|
复制出来后存储在一个新的`txt`文本中,新建一个`Excel`工作表,在 **数据** 选项卡中选择 **从文本/CSV** 中获取数据
|
|||
|
|
|||
|

|
|||
|
|
|||
|
选择刚刚新建的`txt`文本,进行导入
|
|||
|
|
|||
|

|
|||
|
|
|||
|
分隔符选择 **逗号**,选择 **转换数据**
|
|||
|
|
|||
|

|
|||
|
|
|||
|
这将会打开`Power Query`编辑器,根据逗号拆出的所有数据会汇总到一行当中,选择 **转换** 选项卡,选择 **转置** 选项,可以将一行的数据转换成一列
|
|||
|
|
|||
|

|
|||
|
|
|||
|
再选择 **主页** → **拆分列** → **按分隔符** 进行拆分
|
|||
|
|
|||
|

|
|||
|
|
|||
|
选择分隔符为等号,引号字符为无,点击确定
|
|||
|
|
|||
|

|
|||
|
|
|||
|
得到拆分结果后选择 **关闭并上载**
|
|||
|
|
|||
|

|
|||
|
|
|||
|
数据会写入到`Excel`表中,使用`LEN`函数统计出第二列中字符串的长度
|
|||
|
|
|||
|

|
|||
|
|
|||
|
通过筛选找出所有长度大于`255`的行,拿第一列的值到新建的`txt`文本中搜索,确认这是一个属性
|
|||
|
|
|||
|
> 表格中的数据只是进行了粗略的处理,不一定正确,需要找到正确的属性才行
|
|||
|
>
|
|||
|
> 
|
|||
|
>
|
|||
|
> objpropnames则是正确的属性
|
|||
|
>
|
|||
|
> 
|
|||
|
|
|||
|
打开服务器上的`SSMS`,连接`plmv8`数据库,执行如下`sql`语句
|
|||
|
|
|||
|
```sql
|
|||
|
/*
|
|||
|
if exists(Select * From syscolumns where id=Object_ID('cfobjkind') and Name='columnName'): 这一行是在检查cfobjkind表中是否存在名为columnName的列。syscolumns是一个系统表,它包含了数据库中所有对象(如表和视图)的列信息。Object_ID('cfobjkind')返回cfobjkind对象的ID,如果该对象不存在则返回NULL
|
|||
|
begin ... end: 如果上述条件为真(即存在这样的列),那么执行begin和end之间的语句
|
|||
|
Alter Table cfobjkind alter column defaultvalue nvarchar(max): 这行命令尝试更改cfobjkind表中columnName列的数据类型为nvarchar(max)。nvarchar(max)表示可变长度的Unicode字符数据,最大长度为2^31-1个字符
|
|||
|
*/
|
|||
|
if exists(Select * From syscolumns where id=Object_ID('cfobjkind') and Name='columnName')
|
|||
|
begin
|
|||
|
Alter Table cfobjkind alter column columnName nvarchar(max)
|
|||
|
end
|
|||
|
Go
|
|||
|
```
|
|||
|
|
|||
|
==切记执行上述语句前,**将`columnName`替换成查找出来的属性**==
|
|||
|
|
|||
|
执行完语句后,再保存常规属性界面时,就不会报错了(再报错说明改的属性不对,需要排查其他属性)
|
|||
|
|
|||
|
# 问题原因
|
|||
|
|
|||
|
报错是因为要存储的值超过了数据库中该字段可存储的值的长度上限
|
|||
|
|
|||
|
> 以`objpropnames`字段为例,这是存储对象分类的常规属性界面中所有的属性名的,在上例中,`objpropnames`要存储的值长度为4334,而数据库中仅能存储长度为4000的值,故而出现了报错,只要将这个字段的类型改成nvarchar(max)即可
|