2017-08-24 86 views
0

我想解决以下问题: 我需要准备包含3列的表格: user_id, 月份 值。 来自200多个用户的每个用户都获得了不同的参数值,这些值确定期望值,即:LOB,CHANNEL和SUBSIDIARY。所以我决定将它存储在ASYSTENT_GOALS_SET表中。但我想避免乘以行,并认为将所有条件作为代码的一部分,我将在过程中的“where”子句中进一步使用。 所以,作为一个例子 - 而不是多行:如何将代码的一部分作为字符串放入表中以在过程中使用它?

enter image description here

我创造了这样的条目: enter image description here

到目前为止,我创建测试表ASYSTENT_TEST(这里我收集月和值对某些用户) 。我用BULK COLLECT写了一段程序。

declare 
    type test_row is record 
    (
    month NUMBER, 
    value NUMBER 
); 
    type test_tab is table of test_row; 
    BULK_COLLECTOR test_tab; 
    p_lob varchar2(10) :='GOSP'; 
    p_sub varchar2(14); 
    p_ch varchar2(10) :='BR'; 
    begin 
    select subsidiary into p_sub from ASYSTENT_GOALS_SET where user_id='40001001'; 
    execute immediate 'select mc, sum(ppln_wartosc) plan from prod_nonlife.mis_report_plans 
    where report_id = (select to_number(value) from prod_nonlife.view_parameters where view_name=''MIS'' and parameter_name=''MAX_REPORT_ID'') 
    and year=2017 
    and month between 7 and 9 
    and ppln_jsta_symbol in (:subsidiary) 
    and dcs_group in (:lob) 
    and kanal in (:channel) 
    group by month order by month' bulk collect into BULK_COLLECTOR 
    using p_sub,p_lob,p_ch; 
    forall x in BULK_COLLECTOR.first..BULK_COLLECTOR.last insert into ASYSTENT_TEST values BULK_COLLECTOR(x); 
end; 

所以,现在当表ASYSTENT_GOALS_SET列附属(VARCHAR)由字符串12_00_00(这是子公司之一的代码),一切工作正常。但问题是当用户在两个子公司工作时,比如说12_00_00和13_00_00。我不知道如何写下来。如果明细栏包括: “12_00_00”,“13_00_00” 或 “12_00_00”,“13_00_00” 13_00_00 我已经挖主题,如“德灵单后尝试了很多的选项 也许 12_00_00' ,'/逃脱/双重qoutes“。 也许我应该改变立即执行的东西?

或者,也许我从这个问题的方法是从一开始就完全错误(希望不:))。 我将不胜感激的支持。

+0

如果我理解正确,那么不工作的部分是(:子公司)中的'ppln_jsta_symbol'? – Dessma

+0

是的,Dessma,确切地说。除了上面提到的表ASYSTENT_GOALS_SET列SUBSIDIARY之外,我还尝试将ppln_jsta_symbol的代码切换到子公司,并将('12_00_00','13_00_00')作为子公司。我也尝试使用regexp_substr从我的SUBSIDIARY列中的字符串中读取数据,但没有成功。 –

+1

我无法给你写一个工作示例,因为我现在无法访问我的数据库,但我相信你的答案的很大一部分可以在标题为“使用TABLE函数”的部分找到:https:// www.quartchinfo.co.uk/delimited_lists_to_collections.html#plsql_function 基本上你可以将你的元素字符串转换成TABLE,然后使用NOT IN(SELECT * FROM TABLE(f_convert(yourString)))。希望这是有道理的。 – Dessma

回答

0

我没有创建here所描述的表函数,但那篇文章启发了我再次尝试regexp_substr函数。
我改变了:
ppln_jsta_symbol in (:subsidiary)

ppln_jsta_symbol in (select regexp_substr((select subsidiary from ASYSTENT_GOALS_SET where user_id=''fake_num''),''[^,]+'', 1, level) from dual connect by regexp_substr((select subsidiary from ASYSTENT_GOALS_SET where user_id=''fake_num''), ''[^,]+'', 1, level) is not null)
现在它就像一个魅力!谢谢@Dessma非常感谢您的时间和建议!

0

“我想避免乘行,并认为这将是很好的把所有的条件,我会在‘那里’条款进一步程序使用代码的一部分”

这似乎一个误导的要求。您不应该担心行数:数据库针对存储和检索行进行了优化。

他们不善于处理“多值”栏。正如你自己的解决方案所证明的那样,这不是很好,它远非好事,实际上它是一个完全痛苦的脖子。从现在开始,每当有人需要使用subsidiary时,他们将不得不调用一个函数。添加,更改或删除用户的子公司比它应该更加困难。也没有机会强制执行数据完整性,即验证子公司对照参考表是否有效。

也许这些都不重要给你。但是,为什么科德要求“不重复的团体”作为建立健全的数据模型的基础步骤First Normal Form的标准有很好的理由。

正确的解决方案,近40年的行业最佳实践将认识到SUBSIDIARY与CHANNEL存在不同的粒度,因此应存储在单独的表格中。

+0

感谢您的评论。我仍然在学习,如前所述,我怀疑这不是一个好方法。我意识到这不是数据存储在表格中的方式。通常我会根据用户ID的需要准备许多行,以便有唯一的条目:USER ID,CHANNEL和SUBSIDIARY,以便稍后进行适当的选择。
长话短说我正在寻找一些简单的方法来为那些将负责更换用户的子公司的人员。 –

相关问题