Используйте представления и табличные функции как таблицы узлов или ребер в предложениях соответствия
Мне нравится использовать табличные функции в MATCH
пункты так же, как это возможно с Node
таблицы Есть ли способ добиться этого?
Потребность в табличных функциях
Возможны различные варианты использования табличных функций или представлений в качестве Node
таблицы Например, мое следующее.
я имею Node
таблицы, содержащие NVarChar(max)
поля, которые я хотел бы найти для буквального текста. Мне нужен только поиск по равенству и полнотекстовый поиск, поэтому я решил использовать индекс для значения хеш-функции текстового поля. Как предложил Remus Rusanu в своем ответе на SQL-сервер, стоит ли индексировать большие строковые ключи? и https://www.brentozar.com/archive/2013/05/indexing-wide-keys-in-sql-server/. Табличная функция обрабатывает, используя CHECKSUM
индекс; см. сообщение 207 Неверное имя столбца $node_id для псевдостолбца во встроенной табличной функции.
Пример определения данных
CREATE TABLE [Tags](
[tag] NVarChar(max),
[tagHash] AS CHECKSUM([Tag]) PERSISTED NOT NULL
) as Node;
CREATE TABLE [Sites](
[endPoint] NVarChar(max),
[endPointHash] AS CHECKSUM([endPoint]) PERSISTED NOT NULL
) as Node;
CREATE TABLE [Links] as Edge;
CREATE INDEX [IX_TagsByName] ON [Tags]([tagHash]);
GO
CREATE FUNCTION [TagsByName](
@tag NVarChar(max))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT
$node_id AS [NodeId],
[tag],
[tagHash]
FROM [dbo].[Tags]
WHERE [tagHash] = CHECKSUM(@tag) AND
[tag] = @tag;
[TagsByName]
возвращает $node_id
с псевдонимом NodeId
как предложено /questions/25820397/msg-207-nevernoe-imya-stolbtsa-nodeid-dlya-psevdostolbtsa-vo-vstroennoj-tablichnoj-funktsii/25820404#25820404. Однако настоящий Node
таблицы содержат еще два внутренних столбца, которые я не знаю, как экспортировать.
Желаемый запрос
Я хотел бы запросить базу данных, подобную этой:
SELECT *
FROM [TagsByName]('important') as t,
[Sites] as s,
[Links] as l
WHERE MATCH ([t]-([l])->[s])
Однако это приводит к ошибке 1:
Сообщение 13901, Уровень 16, Состояние 2, Линия...
Идентификатор "т" вMATCH
Предложение не является таблицей узлов или псевдонимом для таблицы узлов.
Есть ли способ сделать это?
PS. Есть некоторые обходные пути, но они не выглядят так элегантно, как MATCH
-query; особенно учитывая, что мой фактический запрос включает в себя сопоставление большего количества отношений и больше тестов на равенство строк. Я опубликую эти обходные пути как ответы и надеюсь, что кто-то придет с лучшей идеей.
1 Это дает очень специфическую разницу между представлениями и таблицами для разницы между представлением и таблицей в sql; что происходит только в /questions/tagged/sql-server-2017 и только при использовании SQL Graph.
3 ответа
Временное решение
Добавить Node
table дважды к предложению from: один раз как таблица и один раз как функция с табличным значением и присоедините их через $node_id
в предложении where:
SELECT *
FROM [TagsByName]('important') as t1,
[Tags] as t2,
[Sites] as s,
[Links] as l
WHERE MATCH ([t2]-([l])->[s]) AND
t1.[NodeId] = t2.$node_id
Влияет ли это на производительность?
Временное решение
Возврат к традиционным реляционным соединениям через JOIN
пункты или FROM
с <table_or_view_name>
а также WHERE
статьи. В запросах, которые соответствуют большему количеству отношений, последний имеет преимущество в том, что /questions/tagged/sql-server-2017-graph может MATCH
на FROM <table_or_view_name>
но не на FROM <table_source> JOIN <table_source>
,
SELECT *
FROM [TagsByName]('important') as t
[Sites] as s,
[Links] as l
WHERE t.NodeId = l.$from_id AND
l.$to_id = s.$node_id;
Временное решение
Не используйте табличную функцию, но включите ее выражение в WHERE
пункт:
SELECT *
FROM [Tags] as t,
[Sites] as s,
[Links] as l
WHERE MATCH ([t]-([l])->[s]) AND
[t].[tagHash] = CHECKSUM('important') AND
[t].[tag] = 'important'
Недостаток: это легко ошибиться; например, забыв присоединиться к CHECKSUM