我喜欢在Table Valued functions条款中使用MATCH
,方法与Node
tables相同。有没有办法实现这个目标?
将表值函数或视图用作Node
tables可以有多种用例。例如我的如下
我有Node
个包含NVarChar(max)
个字段的表,我想搜索文字文本。我只需要平等搜索而不需要full text searching,所以我选择在文本字段的hash value上使用索引。正如Remus Rusanu在answer至SQL server - worth indexing large string keys?和https://www.brentozar.com/archive/2013/05/indexing-wide-keys-in-sql-server/中所建议的那样。使用CHECKSUM
索引的表值函数句柄;见Msg 207 Invalid column name $node_id for pseudo column in inline table valued function。
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
返回https://stackoverflow.com/a/45565410/814206。但是,真正的Node
tables包含两个内部列,我不知道如何导出。
我想查询与此类似的数据库:
SELECT *
FROM [TagsByName]('important') as t,
[Sites] as s,
[Links] as l
WHERE MATCH ([t]-([l])->[s])
但是,这会导致错误 1 :
Msg 13901,Level 16,State 2,Line ...
MATCH
子句中的标识符't'不是node table或节点表的别名。
我有办法做到这一点吗?
PS。有一些解决方法,但它们看起来不像MATCH
- 查询那么优雅;特别是考虑到我的实际查询涉及匹配更多关系和更多字符串相等测试。我会将这些变通方法作为答案发布,并希望有人能提出更好的想法。
1 这为Difference between View and table in sql的视图和表格提供了非常具体的区别;仅在sql-server-2017中出现且仅在使用SQL Graph时出现。
答案 0 :(得分:0)
通过JOIN
子句或FROM
with <table_or_view_name>
和WHERE
子句恢复传统的关系联接。在match关于更多关系的查询中,后者的优势是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;
答案 1 :(得分:0)
将Node
表两次添加到from子句:一次作为表,一次作为表值函数,并通过where子句中的$node_id
加入它们:
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
这会影响效果吗?
答案 2 :(得分:0)
不要使用表值函数,而是在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