Oracle查询数据,其中列值使用逗号检查值是否包含

Oracle查询数据,其中列值使用逗号检查值是否包含,oracle,Oracle,我想查询数据以检查至少包含1个IP地址 例如,我有以下数据: PROFILEID PROFILE_NAME ACTIVE DATEADDED ADDEDBY LOCATIONID_FK ALLOWED_IP_ADDRESS PF0001 Normal Working Day Y 9/30/2017 5:53:39 PM US0001 LC0001 192.168.183.205, 192.168

我想查询数据以检查至少包含1个IP地址

例如,我有以下数据:

PROFILEID   PROFILE_NAME        ACTIVE  DATEADDED               ADDEDBY LOCATIONID_FK   ALLOWED_IP_ADDRESS
PF0001      Normal Working Day  Y       9/30/2017 5:53:39 PM    US0001  LC0001          192.168.183.205, 192.168.183.28
PF0004      Ramadhan            N       10/12/2017 10:38:02 AM  US0001  LC0003  
PF0002      Ramadhan            N       9/30/2017 5:55:50 PM    US0001  LC0001          192.168.183.205, 192.168.183.28
PF0003      Normal Working Day  Y       10/3/2017 5:23:05 PM    US0001  LC0003          192.168.184.20, 192.168.184.15
如您所见,列
允许的\u IP\u地址
有更多的带有逗号的IP

现在我想用query检查一下,
在('192.168.183.28')中允许IP地址,但没有得到结果

SELECT PROFILEID FROM WA_BT_TBL_PROFILE P WHERE P.ALLOWED_IP_ADDRESS IN ('192.168.183.28');

如何进行正确的查询?

请改用
类似的

SELECT PROFILEID FROM WA_BT_TBL_PROFILE P WHERE P.ALLOWED_IP_ADDRESS LIKE '%192.168.183.28%'
以上是一个“肮脏的修复”坏表使用。应避免在同一条目上存储串联字符串。
还要考虑到上述查询对于给定IP的子集是有效的。以上IP将保证您得到正确的结果,但是使用类似192.168.183.2的IP可能会带来不需要的条目,例如192.16.183.21,…

使用类似的

SELECT PROFILEID FROM WA_BT_TBL_PROFILE P WHERE P.ALLOWED_IP_ADDRESS LIKE '%192.168.183.28%'
以上是一个“肮脏的修复”坏表使用。应避免在同一条目上存储串联字符串。
还要考虑到上述查询对于给定IP的子集是有效的。上面的IP将保证您得到正确的结果,但是使用类似192.168.183.2的IP可能会带来不需要的条目,例如192.16.183.21,…

如果您要查找精确匹配项,可以使用
类似的
条件或
instr
函数,但需要在两侧串联逗号,如:

select profileid
  from wa_bt_tbl_profile p
 where ', ' || p.allowed_ip_address || ',' like '%, 192.168.183.28,%'
[编辑] 如果在比较IP地址时不使用逗号,则可能会得到不需要的结果-例如,如果使用地址10.10.10.10进行比较,如果没有逗号,则有效结果也将是110.10.10.10、10.10.10.101、110.10.10.101等


我建议您删除逗号和IP地址之间的空格-这只会使代码更难理解。

如果您要查找精确的匹配项,可以使用
类似的
条件或
instr
函数,但您需要在两侧串联逗号,如:

select profileid
  from wa_bt_tbl_profile p
 where ', ' || p.allowed_ip_address || ',' like '%, 192.168.183.28,%'
[编辑] 如果在比较IP地址时不使用逗号,则可能会得到不需要的结果-例如,如果使用地址10.10.10.10进行比较,如果没有逗号,则有效结果也将是110.10.10.10、10.10.10.101、110.10.10.101等


我建议您删除逗号和IP地址之间的空格-这只会使代码更难理解。

您需要检查是否有被分隔符包围的子字符串:

SELECT PROFILEID
FROM   WA_BT_TBL_PROFILE P
WHERE  ', ' || P.ALLOWED_IP_ADDRESS || ', ' LIKE '%, 192.168.183.28, %';
但是,更好的方法是更改数据库表,这样就不会在一个值中存储多个项:

CREATE TABLE Allowed_IP_Addresses(
  PROFILEID          VARCHAR2(20)
                     CONSTRAINT AllowIP__ProfileID__FK REFERENCES WA_BT_TBL_PROFILE( PROFILEID ),
  CLASSA             NUMBER(3,0),
  CLASSB             NUMBER(3,0),
  CLASSC             NUMBER(3,0),
  CLASSD             NUMBER(3,0),
  IP_ADDRESS         VARCHAR2(15)
                     GENERATED ALWAYS AS (CLASSA||'.'||CLASSB||'.'||CLASSC||'.'||CLASSD) VIRTUAL,
  CONSTRAINT AllowIP__P_A_B_C_D__PK PRIMARY KEY ( PROFILEID, CLASSA, CLASSB, CLASSC, CLASSD )
);

然后,您可以单独存储这些值(并轻松搜索子网范围),并根据需要将其连接到配置文件表。

您需要检查由分隔符包围的子字符串:

SELECT PROFILEID
FROM   WA_BT_TBL_PROFILE P
WHERE  ', ' || P.ALLOWED_IP_ADDRESS || ', ' LIKE '%, 192.168.183.28, %';
但是,更好的方法是更改数据库表,这样就不会在一个值中存储多个项:

CREATE TABLE Allowed_IP_Addresses(
  PROFILEID          VARCHAR2(20)
                     CONSTRAINT AllowIP__ProfileID__FK REFERENCES WA_BT_TBL_PROFILE( PROFILEID ),
  CLASSA             NUMBER(3,0),
  CLASSB             NUMBER(3,0),
  CLASSC             NUMBER(3,0),
  CLASSD             NUMBER(3,0),
  IP_ADDRESS         VARCHAR2(15)
                     GENERATED ALWAYS AS (CLASSA||'.'||CLASSB||'.'||CLASSC||'.'||CLASSD) VIRTUAL,
  CONSTRAINT AllowIP__P_A_B_C_D__PK PRIMARY KEY ( PROFILEID, CLASSA, CLASSB, CLASSC, CLASSD )
);

然后,您可以单独存储这些值(并方便地搜索子网范围),并根据需要将其连接到配置文件表。

如“%19.168.183.25%”
将匹配
19.168.183.25
以及
219.168.183.25
19.168.183.256
119.168.183.250
(除其他外)@MT0我写的是192.168.183.28而不是19.168.183.25,这意味着280 0r 28x不是一个选项…另外19.168.183.256不是一个有效的IP,请在你之前检查一下post@GoranStefanović. Gyus请思考…在你发布之前,28x不能是一个有效的结束IP。IP增加到255。280或281或289,或。。。。是无效的IP@apomene:关于范围,您是对的,但谁能说OP不会将地址与10.1.1.5 tommorow进行比较?MT0的示例基于这样的假设,即OP不会始终与该地址进行比较,但要求会随时间而变化。我们应该提供可重用的查询,而不仅仅是适用于一个特定情况的查询。
如“%19.168.183.25%”
将匹配
19.168.183.25
,以及
219.168.183.25
19.168.183.256
119.168.183.250
(以及其他许多情况)。@MT0我写的是192.168.183.28而不是19.168.183.25,这意味着280 0r 28x不是一个选项…而且19.168.183.256不是一个有效的IP,请在您之前查看某个内容post@GoranStefanović. Gyus请思考…在你发布之前,28x不能是一个有效的结束IP。IP增加到255。280或281或289,或。。。。是无效的IP@apomene:关于范围,您是对的,但谁能说OP不会将地址与10.1.1.5 tommorow进行比较?MT0的示例基于这样的假设,即OP不会始终与该地址进行比较,但要求会随时间而变化。我们应该提供可重用的查询,而不仅仅是针对特定情况的查询。是的,这有什么问题?查询将返回它。这就是为什么我在p.allowed\u ip\u地址周围添加逗号的原因。是的,这有什么问题?查询将返回它。这就是为什么我在p.allowed_ip_address周围添加了逗号。@apomene
WHERE'、“|p.allowed_ip_address |”、“LIKE
这就是为什么列在前后添加了分隔符,所以在这种情况下它仍然是匹配的。@HiDayurie Dave:请注意,使用like的解决方案将不允许您比较多个IP地址。您必须将IP地址从表中的字符串中分割出来,这会使事情变得相当复杂。因此,请遵循MT0给出的建议来规范化数据-这将帮助您编写更易于维护的代码,并提供更好的性能。@apomene
WHERE'、“|P.ALLOWED_IP_ADDRESS | |”、”LIKE
,这就是为什么列在前后添加了分隔符,所以在这种情况下它仍然是匹配的。@HiDayurie Dave:请注意,使用like的解决方案将不允许您比较多个IP地址。您必须将IP地址从表中的字符串中分割出来,这会使事情变得相当复杂。因此,请遵循MT0给出的建议来规范化数据-这将帮助您编写更易于维护的代码