Запрос на получение уникального индекса и первичных ключей таблицы MsSQL - PullRequest
1 голос
/ 23 февраля 2009
SELECT sysobjects.xtype, syscolumns.name, sysindexkeys.indid, sysobjects.type
FROM
    syscolumns
LEFT JOIN sysobjects ON syscolumns.id = sysobjects.id
LEFT JOIN sysindexkeys ON (
     syscolumns.id = sysindexkeys.id AND syscolumns.colid = sysindexkeys.colid
)
WHERE sysobjects.name = '{$table}'
AND sysindexkeys.indid IS NOT NULL
ORDER BY sysindexkeys.indid, sysindexkeys.keyno

Я на самом деле использую следующий запрос для получения имени столбца и ключа.

Проблема в том, что в моей таблице 3 поля:

user_id
config_name
config_value

С первичным ключом для user_id И config_name.

Я бы ожидал получить коллекцию:

[
  ['name' => 'user_id', 'keyno' => 1],
  ['name' => 'config_name', 'keyno' => 1]
]

Но я получаю:

[
  ['name' => 'user_id', 'keyno' => 1],
  ['name' => 'config_name', 'keyno' => 2]
]

Что я делаю не так?

редактирование: Я получаю те же самые странные результаты, используя таблицу с двумя индексами

таблица: project_image_id project_id project_image_src

PK для project_image_id И уникальный индекс для project_id И project_image_src

Ожидаемый:

[
  ['name' => 'project_image_id', 'keyno' => 1],
  ['name' => 'project_id', 'keyno' => 2]
  ['name' => 'project_image_src', 'keyno' => 2]
]

Но я получаю:

[
  ['name' => 'project_image_id', 'keyno' => 1],
  ['name' => 'project_id', 'keyno' => 1]
  ['name' => 'project_image_src', 'keyno' => 2]
]

Ответы [ 6 ]

2 голосов
/ 26 октября 2010

Существует пара достойных решений первичного ключа, но они не полностью отвечают на запрос. Был также задан вопрос, как определить, является ли столбец уникальным индексом.

Вариант 1:

Чтобы определить уникальный индекс, следующая системная функция сообщает вам состояние определенного индекса, «IndexName» в таблице «TableName»:

SELECT INDEXPROPERTY(OBJECT_ID('TableName'),'IndexName','IsUnique')

Вариант 2:

Однако приведенный выше вопрос связан с желанием узнать, является ли КОЛОННА уникальным индексом. Это означает, что вам нужен список всех индексов, для которых рассматриваемый столбец является единственным столбцом в индексе. Поэтому можно использовать такую ​​комбинацию:

-- Note: If a "1" appears in the select below, the index (and by extension, the column) is a unique index.


SELECT si.name, INDEXPROPERTY(x.TableID,si.name,'IsUnique') [IsUnique]
FROM sysindexes si
JOIN (SELECT OBJECT_ID('TableName') [TableID]) x  -- HERE IS YOUR TABLE NAME
  ON si.id = x.TableID
-- This restricts the selection to your column.
JOIN (
    SELECT id, indid 
    FROM sysindexkeys
    WHERE colid IN (
        -- For 2005 and up: SELECT COLUMNPROPERTY(OBJECT_ID('TableName'), 'ColumnName', 'ColumnId')
        SELECT colid
        FROM syscolumns
        WHERE name IN ('ColumnName')              -- HERE IS YOUR COLUMN NAME
    )
) y
  ON si.indid = y.indid
 AND x.TableID = y.id
WHERE si.status <> 0
  -- This eliminates occurrences of the column found in indexes with multiple columns.
  AND si.indid NOT IN (
    SELECT indid
    FROM sysindexkeys
    WHERE id = x.TableID
    GROUP BY indid
    HAVING COUNT(*) > 1
)

Вариант 3:

Создайте таблицу (IndexTable) с index_name, index_description, index_keys и вставьте результаты следующей команды:

sp_helpindex 'TableName'

Затем запросите этот результат (или используйте аналогичный запрос):

SELECT *
FROM IndexTable
WHERE index_description LIKE '%unique%'
  AND index_keys = 'ColumnName'

Надеюсь, это поможет, или, пожалуйста, напишите, если у вас есть более краткое решение.

2 голосов
/ 23 февраля 2009

Мне кажется, что ваш индекс имеет 2 столбца, user_id имеет позицию 1, а config_name имеет позицию 2

От BOL keyno: Положение столбца в индексе

почему вы думаете, что они оба будут равны 1?

Итак, вам нужно присоединиться к таблице sysobject, но по индексу, а не к самой таблице

SELECT s2.xtype, syscolumns.name, sysindexkeys.indid, sysobjects.type
FROM
    syscolumns
LEFT JOIN sysobjects ON syscolumns.id = sysobjects.id
LEFT JOIN sysindexkeys ON (
     syscolumns.id = sysindexkeys.id AND syscolumns.colid = sysindexkeys.colid
)
join sysobjects s2 on s2.parent_obj = sysindexkeys.id
WHERE sysobjects.name = '{$table}'
and s2.type = 'K'
AND sysindexkeys.indid IS NOT NULL
ORDER BY sysindexkeys.indid, sysindexkeys.keyno
1 голос
/ 04 мая 2011
select sc.name 
  from sys.indexes si 
          join sys.tables st 
             on si.object_id = st.object_id
          join sys.index_columns sic 
             on sic.object_id = si.object_id and 
                sic.index_id = si.index_id
          join sys.columns sc 
             on sic.object_id = sc.object_id and 
                sic.column_id = sc.column_id
  where st.name = @table_name and 
        si.is_primary_key = 1
  order by sic.index_column_id 
1 голос
/ 25 февраля 2011

Попробуйте этот запрос:

SELECT A.TABLE_NAME, A.CONSTRAINT_NAME, B.COLUMN_NAME
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS A, 
         INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE B
    WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' AND
          A.CONSTRAINT_NAME = B.CONSTRAINT_NAME AND
          A.TABLE_NAME='{$tableName}'
    ORDER BY A.TABLE_NAME

Замените {$tableName} на имя таблицы, и вы получите все первичные ключи для конкретной таблицы, независимо от того, имеет ли таблица один первичный ключ или несколько первичных ключей.

0 голосов
/ 19 мая 2009
SELECT sysobjects.name , syscolumns.name, systypes.name, syscolumns.length ,
       syscolumns.xprec , syscolumns.xscale ,

( 
SELECT 'PK'
  FROM syscolumns C
 WHERE C.name = syscolumns.name AND C.id IN (SELECT O.id
                  FROM sysobjects O
                 WHERE O.name = sysobjects.name)
   AND C.colid IN (SELECT SIK.colid 
                   FROM sysindexkeys SIK 
                   JOIN sysobjects SO ON SIK.id= SO.id  
                  WHERE SIK.indid = 1
                    AND SO.[name] = sysobjects.name)
)
FROM 
    sysobjects , syscolumns 
       , systypes  
    WHERE 
    sysobjects.xtype='U' 
    AND sysobjects.id = syscolumns.id AND syscolumns.xtype=systypes.xtype
    AND sysobjects.name LIKE ?
 ORDER BY sysobjects.name  , syscolumns.COLORDER
0 голосов
/ 23 февраля 2009

Проблема в том, что вы получаете «Положение столбца в индексе». Таким образом, не существует двух столбцов с одинаковым положением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...