校验全库缺失某列索引的全部表列表-sybase ase版本

--创建函数
USE tempdb
GO

IF OBJECT_ID ('dbo.P_QueryLostColIndex') IS NOT NULL
        DROP PROCEDURE dbo.P_QueryLostColIndex
GO

CREATE PROCEDURE P_QueryLostColIndex(
     @dbname_prefix VARCHAR(300), --数据库前缀名
     @col_name      VARCHAR(300)  --字段名
     )
AS
BEGIN
  DECLARE
    @tmpSql          VARCHAR(900),
    @dbname          VARCHAR(300),
    @tablename       VARCHAR(300),
    @tableid         INT,
    @indid           INT,
    @lostIndex       INT,
    @i               INT

  CREATE TABLE #tmp_lost_col_index(
    dbname VARCHAR(300),
    tablename VARCHAR(300)
  )
  
  CREATE TABLE #tmp_tbs(
    tablename VARCHAR(300),
    tableid INT
  )
  
  CREATE TABLE #tmp_idx(
    indid INT
  )
           
  --1.定义游标(所有符合前缀条件的库名)
  DECLARE dbs CURSOR FOR SELECT name FROM master..sysdatabases WHERE name LIKE @dbname_prefix + '%'
  --2.打开游标
  OPEN dbs
  --3.获取记录
  FETCH dbs INTO @dbname  
  --4.循环处理每个库
  WHILE @@SQLSTATUS = 0
  BEGIN
    --4.1 清空临时表
    TRUNCATE TABLE #tmp_tbs
   
    --4.2处理临时表
    SELECT @tmpSql = "INSERT INTO #tmp_tbs SELECT name, id FROM " + @dbname + "..sysobjects WHERE type = 'U' AND EXISTS (SELECT 1 FROM " + @dbname + "..syscolumns WHERE name = '" + @col_name + "' AND id = " + @dbname + "..sysobjects.id)"
    PRINT @tmpSql
    EXECUTE (@tmpSql)
   
    --4.2.1 定义表列表游标
    DECLARE tbs CURSOR FOR SELECT tablename, tableid FROM #tmp_tbs
    --4.2.2 打开表列表游标
    OPEN tbs
    --4.2.3 获取记录
    FETCH tbs INTO @tablename, @tableid
    --4.2.4状态为正常
    WHILE @@SQLSTATUS = 0
    BEGIN
      --4.2.5处理所有索引
      TRUNCATE TABLE #tmp_idx
      SELECT @tmpSql = "INSERT INTO #tmp_idx SELECT indid FROM " + @dbname + "..sysindexes WHERE id = " + CONVERT(VARCHAR, @tableid) + " AND indid > 0 AND indid < 255"
      EXECUTE (@tmpSql)
      
      SELECT @lostIndex = -1
      --4.2.5.1 循环处理每个索引
      DECLARE idxs CURSOR FOR SELECT indid FROM #tmp_idx
      OPEN idxs
      FETCH idxs INTO @indid
      WHILE @@SQLSTATUS = 0
      BEGIN
            SELECT @i = 1
            WHILE @i <= 31
            BEGIN            
              --如果字段相同,则修改状态并跳出循环
              IF index_col(@dbname + '..' + @tablename, @indid, @i) = @col_name
              BEGIN
                SELECT @lostIndex = 1
                BREAK
              END
              SELECT @i = @i + 1
            END
            --标记大于1时代表对应字段在索引中最低出现了一次,判断下一个表
            IF @lostIndex > -1
            BEGIN
              BREAK
            END
            FETCH idxs INTO @indid
      END
      CLOSE idxs
      DEALLOCATE CURSOR idxs
      
      IF @lostIndex < 0
      BEGIN
        INSERT INTO #tmp_lost_col_index SELECT @dbname, @tablename
      END
      
      --4.2.6处理下一条
      FETCH tbs INTO @tablename, @tableid
    END
    CLOSE tbs
    DEALLOCATE CURSOR tbs
   
    --4.3 处理下一条
        FETCH dbs INTO @dbname
  END
  --5.关闭游标
  CLOSE dbs
  --6.销毁游标
  DEALLOCATE CURSOR dbs
   
  
  SELECT dbname, tablename FROM #tmp_lost_col_index
   
  DROP TABLE #tmp_idx  
  DROP TABLE #tmp_tbs
  DROP TABLE #tmp_lost_col_index
END

GO

--执行函数
--执行完毕后返回的结果集就是我们想要的结果。在需要时也可以修改存储过程中的临时表为实体表,根据需求调整即可
USE tempdb
GO

EXECUTE tempdb..P_QueryLostColIndex 'DB_TASK', 'N_AJBS'
GO

猜你喜欢

转载自blog.csdn.net/leandzgc/article/details/103053453