• 分享一个使用get_hash_value比对数据脚本


    使用get_hash_value获取每个字段的值,再sum起来比对,如果表有lob字段,则会先排除掉lob字段再比对其它字段

    这个脚本有两个问题:

    1.如果字段所有的值长度加起来超过4000会报错,比对不了,这种情况一般比较少

    2.二进制数据不支持,例如blob

    脚本需要修改:

    1.DS_CONNECT 和DT_CONNECT配置为需要比对的源端和目标端的连接串

    2.COMP_TYPE如果是1则是比对用户,你将需要比对的用户写到COMP_USER中

    如果是2则是比对指定表,你需要手工将 用户名.表名 写入到tab.txt中

    3.FLAG配置一下比对的标识符,随便写,标识比对的哪个库

    4.配置一下NLS_LANG防止有中文表或者中文字段

    其它:

    比对的结果会在当前目录下,tab.info.xxx是详细结果  tab.err.xxx是比对不一致的表 tab.ok.xxx是比对一致的表,上次比对的结果保存在history目录下

    如果比对过程中出现报错,可以检查.c.done和.c.done.bak这两个个隐藏文件

    .hash.sql和.hash.sql.bak是具体执行的sql语句

    1. #!/bin/bash
    2. . ~/.bash_profile
    3. ##### ERROR:: integer expression expected : table no columns without unsupport datatype columns
    4. ##### ERROR:: ORA-01489 : column values concat larger then 40000, unsupport
    5. export WORKDIR=$(cd `dirname $0`/; pwd)
    6. ##modify
    7. ##USER and PWD
    8. export FLAG=wzjj_lob
    9. export DS_CONNECT=xx/xxxx@source
    10. export DT_CONNECT=xx/xxxx@target
    11. export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
    12. ###COMP_TYPE:1-user 2-table
    13. ###if COMP_TYPE=1,please modify COMP_USER
    14. ###if COMP_TYPE=2,plase write OWNER.TABLE_NAME to $TABLE_FILE
    15. export COMP_TYPE=1
    16. export COMP_USER="('BUSINESS_QRY','TEST')"
    17. export TABLE_FILE=$WORKDIR/tab.txt
    18. ####init tab.txt
    19. if [ $COMP_TYPE -eq 1 ]
    20. then
    21. sqlplus -S $DS_CONNECT <<EOF >$WORKDIR/tab.txt
    22. set pagesize 0 feedback off verify off heading off echo off long 9999 longchunksize 9999 line 5000
    23. select owner||'.'||table_name from dba_tables where owner in $COMP_USER
    24. /
    25. EOF
    26. fi
    27. ########
    28. LOGFILE_OPERTIME=`date +%Y%m%d%H%M`
    29. ALL_ROW=`cat $TABLE_FILE |wc -l`
    30. ####check oracle version
    31. VERSION=`sqlplus -S $DS_CONNECT <<EOF
    32. set pagesize 0 feedback off verify off heading off echo off long 9999 longchunksize 9999 line 5000
    33. select substr(value,1,instr(value,'.')-1) from v\\\$parameter where name='compatible'
    34. /
    35. EOF
    36. `
    37. #echo $VERSION
    38. if [ $VERSION -gt 11 ]
    39. then
    40. TSQL=TSQL12C
    41. else
    42. TSQL=TSQL11G
    43. fi
    44. #####################################################################################
    45. TSQL11G(){
    46. EXEC_SQL=`sqlplus -S $DS_CONNECT <<EOF
    47. set pagesize 0 feedback off verify off heading off echo off long 9999 longchunksize 9999 line 5000
    48. select 'select nvl(sum(dbms_utility.get_hash_value('||replace(to_char(
    49. wm_concat(
    50. decode(data_type,'LONG','','LONG RAW','','BLOB','','CLOB','','NCLOB','''0''','"'||COLUMN_NAME||'"')
    51. )),',','||')
    52. ||',0,power(2,30))),0) from "'||owner||'"."'||table_name||'";'
    53. from dba_tab_columns where owner||'.'||table_name='$1' group by owner,table_name
    54. /
    55. EOF
    56. `
    57. echo "$EXEC_SQL" >$WORKDIR/.hash.sql
    58. }
    59. TSQL12C(){
    60. EXEC_SQL=`sqlplus -S $DS_CONNECT <<EOF
    61. set pagesize 0 feedback off verify off heading off echo off long 9999 longchunksize 9999 line 5000
    62. select 'select nvl(sum(dbms_utility.get_hash_value('||to_char(listagg(
    63. decode(data_type,'LONG','','LONG RAW','','BLOB','','CLOB','','NCLOB','''0''','"'||COLUMN_NAME||'"')
    64. ,'||'))
    65. ||',0,power(2,30))),0) from "'||owner||'"."'||table_name||'";'
    66. from dba_tab_columns where owner||'.'||table_name='$1' group by owner,table_name
    67. /
    68. EOF
    69. `
    70. echo "$EXEC_SQL" >$WORKDIR/.hash.sql
    71. }
    72. SOURCE_COUNT(){
    73. SOURCE_NUM=`sqlplus -S $DS_CONNECT <<EOF
    74. set pagesize 0 feedback off verify off heading off echo off numf 999999999999999999999999999999999
    75. @$WORKDIR/.hash.sql
    76. EOF
    77. `
    78. echo s $SOURCE_NUM >> $WORKDIR/.c.done
    79. }
    80. TARGET_COUNT(){
    81. TARGET_NUM=`sqlplus -S $DT_CONNECT <<EOF
    82. set pagesize 0 feedback off verify off heading off echo off numf 9999999999999999999999999999999999
    83. @$WORKDIR/.hash.sql
    84. EOF
    85. `
    86. echo t $TARGET_NUM >> $WORKDIR/.c.done
    87. }
    88. #######################################################################################################
    89. ##init file & backup file
    90. mkdir -p $WORKDIR/history
    91. mv -f $WORKDIR/tab.info* $WORKDIR/history 2>/dev/null
    92. mv -f $WORKDIR/tab.err* $WORKDIR/history 2>/dev/null
    93. mv -f $WORKDIR/tab.ok* $WORKDIR/history 2>/dev/null
    94. date
    95. > $WORKDIR/tab.ok.$LOGFILE_OPERTIME
    96. > $WORKDIR/tab.err.$LOGFILE_OPERTIME
    97. > $WORKDIR/.c.done.bak
    98. > $WORKDIR/.c.done
    99. > $WORKDIR/.hash.sql.bak
    100. printf "%-12s %-10s %-40s %-18s %-18s %-6s %-20s %-20s\n" "ID" "FLAG" "OWNER.TABLE" "DS_HASH" "DT_HASH" "STATUS" "START_TIME" "END_TIME" |tee -a $WORKDIR/tab.info.$LOGFILE_OPERTIME
    101. echo "------------------------------------------------------------------------------------------------------------------------------------------------------------" |tee -a $WORKDIR/tab.info.$LOGFILE_OPERTIME
    102. ID=1
    103. ##########################################################for
    104. while read TABLEINFO
    105. do
    106. cat $WORKDIR/.c.done >>$WORKDIR/.c.done.bak 2>/dev/null
    107. cat $WORKDIR/.hash.sql >>$WORKDIR/.hash.sql.bak 2>/dev/null
    108. > $WORKDIR/.c.done
    109. $TSQL $TABLEINFO
    110. START_OPERTIME=`date +"%Y-%m-%d:%H:%M:%S"`
    111. SOURCE_COUNT $TABLEINFO &
    112. TARGET_COUNT $TABLEINFO &
    113. # ALL_ROW=`echo $TABLE_INFO|awk '{print NF}'`
    114. while true
    115. do
    116. if [ `cat $WORKDIR/.c.done |wc -l ` -eq 2 ]
    117. then
    118. SOURCE_NUM=`cat $WORKDIR/.c.done |awk '$1=="s" {print $2}'`
    119. TARGET_NUM=`cat $WORKDIR/.c.done |awk '$1=="t" {print $2}'`
    120. END_OPERTIME=`date +"%Y-%m-%d:%H:%M:%S"`
    121. if [ $SOURCE_NUM -ne $TARGET_NUM ]
    122. then
    123. COMP_STATUS=2
    124. echo $TABLEINFO >> $WORKDIR/tab.err.$LOGFILE_OPERTIME
    125. else
    126. COMP_STATUS=1
    127. echo $TABLEINFO >> $WORKDIR/tab.ok.$LOGFILE_OPERTIME
    128. fi
    129. printf "%-12s %-10s %-40s %-18s %-18s %-6s %-20s %-20s\n" [$ID/$ALL_ROW] $FLAG $TABLEINFO $SOURCE_NUM $TARGET_NUM $COMP_STATUS $START_OPERTIME $END_OPERTIME |tee -a $WORKDIR/tab.info.$LOGFILE_OPERTIME
    130. break
    131. else
    132. sleep 0.1
    133. fi
    134. done
    135. ID=$(($ID+1))
    136. done <$TABLE_FILE
    137. date

    脚本执行完结果如下:

  • 相关阅读:
    【Java 进阶篇】深入理解 SQL 分组查询
    xgo: golang基于-toolexec实现猴子补丁
    HJ15 求int型正整数在内存中存储时1的个数【C语言】
    Mac电脑使用万能头文件教程(详细)
    jQuery小结五
    创建型设计模式之抽象工厂模式
    渲染流程之应用阶段及几何处理阶段
    为什么我们需要企业架构?
    python库-dotenv包 | .env配置文件
    辉芒微IO单片机FT60F210-URT
  • 原文地址:https://blog.csdn.net/su377486/article/details/134310970