当列"blob"存在时,我有兴趣为整个数据库执行COUNT(*)
、SUM(LENGTH(blob)/1024./1024.)
和ORDER BY SUM(LENGTH(blob))
。对于不存在synchlevels的表,我仍然需要输出。我想GROUP BY
那个栏:
示例
+--------+------------+--------+-----------+|表|同步级别|计数|大小_mb|+--------+------------+--------+-----------+|表A|0|924505|3013.47||表A|7|981|295.33||表格B|6|1449|130.00||表格C|1|64368|68.43||表D|NULL |359|.54||表D|NULL |778|.05|+--------+------------+--------+-----------+
我想做一个纯SQL解决方案,但我在这方面有点困难。目前,我正在将一些SQL封装到BASH中。
#!/bin/bash
USER=$1
DBNAME=$2
function psql_cmd(){
cmd=$1
prefix='pset border 2 \ '
echo $prefix $cmd | psql -U $USER $DBNAME | grep -v "Border| row"
}
function synchlevels(){
echo "===================================================="
echo " SYNCH LEVEL STATS "
echo "===================================================="
tables=($(psql -U $USER -tc "SELECT table_name FROM information_schema.columns
WHERE column_name = 'blob';" $DBNAME))
for table in ${tables[@]}; do
count_size="SELECT t.synchlevel,
COUNT(t.blob) AS count,
to_char(SUM(LENGTH(t.blob)/1024./1024.),'99999D99') AS size_mb
FROM $table AS t
GROUP BY t.synchlevel
ORDER BY SUM(LENGTH(t.blob)) DESC;"
echo $table
psql_cmd "$count_size"
done
echo "===================================================="
}
我可以通过创建第二个tablesBASH表数组来扩展这一点,该数组具有"synchlevel"列,比较并使用该列表来运行SQL,但我想知道是否有一种方法可以让我只在SQL中执行SQL部分,而不必在BASH中列出这些列表并在外部进行比较。即,我希望避免在CCD_ 5中对表进行外部循环和进行大量查询。
我已经尝试了以下SQL在一个表上进行测试,我知道该列不存在。。。
SELECT
CASE WHEN EXISTS(SELECT * FROM information_schema.columns
WHERE column_name = 'synchlevel'
AND table_name = 'archivemetadata')
THEN synchlevel
END,
COUNT(blob) AS count,
to_char(SUM(LENGTH(blob)/1024./1024.),'99999D99') AS size_mb
FROM archivemetadata, information_schema.columns AS info
WHERE info.column_name = 'blob'
但是,对于不存在它的表,它在THEN synchlevel
上失败。这看起来真的很简单,但我似乎找不到一种不需要任何东西的方法:
- 在BASH中使用外部数组比较。
- 可以做到,但我想简化我的解决方案,而不是添加另一层
- 正在创建PL/PGSQL函数。
- 这个脚本实际上只是帮助进行一些数据库数据分析,以提高第三方软件的性能。我们不是DB管理员的商店,所以我不想深入研究PL/PGSQL,因为这需要我们商店的更多人也熟悉这种语言才能支持脚本。同样,简单是这里的动机
Postgresql8.4是引擎。(由于IT监管机构的安全限制,我们无法升级。)
谢谢你的任何建议!
以下内容未经测试,但在一个psql会话中创建一些动态sql并将其管道传输到另一个会话如何?
psql -d <yourdb> -qtAc "
select 'select ' || (case when info.column_name = 'synchlevel' then 'synchlevel,' else '' end) ||
'count(*) as cnt,' ||
'to_char(SUM(LENGTH(blob)::NUMERIC/1024/1024),''99999D99'') AS size_mb' ||
'from ' || info.table_name ||
(case when info.column_name = 'synchlevel' then ' group by synchlevel order by synchlevel' else '' end)
from information_schema.columns as info
where info.table_name IN (select distinct table_name from information_schema.columns where column_name = 'blob')" | psql -d <yourdb>