Query 变量增强(给日期变量设置黙认值为系统当天)

本文介绍如何通过增强BWQuery变量实现默认日期等值的自动填充。重点讲解了使用ABAP代码进行变量处理的方法,包括不同步骤下的变量行为及具体代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BW Query 变量增强(给日期变量设置黙认值为系统当天)

Query 变量增强(给日期变量设置黙认值为系统当天)
1 由于要求在打开报表的时候,弹出一个对话框来输入日期(用于计算)。
在“过滤限制”中添加日期特征,右击选择 ,然后在“显示”输入框处选择“变量”,点击“新增”变量按钮。

在“处理由”处选择“用户出口”。
替换路径功能区为默认.
明细处如果你做的变量是不可输入的话就不对任何复选框做选择,如果是可输入性的,则选中变量已准备输入。其他的功能区就保持默认状态即可,然后点击OK按钮。



在BW系统中运行CMOD进行做增强。
使用"RSR00001" BI: Enhancements for Global Variables in Reporting.


代码,双击:ZXRSRU01
进行编写代码:
data: ls_range like LINE OF E_T_RANGE,
ls_var_range LIKE LINE OF i_t_var_range,
loc_ls_range LIKE LINE OF e_t_range,
gv_date LIKE SY-DATUM.
case I_VNAM. "Name of Variable to be Replaced
WHEN 'VAR_CUTDATE'.
"I_STEP 值说明:
"I_STEP = 1,请直接发生前变量条目。可用于预先填充选择变量。
"I_STEP = 2,呼叫发生后直接变量条目。这一步的时候,才开始了同一个变量是无法输入准备,并且不能在L_STEP = 1填补。
"I_STEP = 3,在此调用,您可以检查变量的值。触发一个异常(提高)导致变量屏幕再次出现。随
"后,L_step = 2,也再次调用。
"I_STEP = 0,是不是从屏幕变量呼吁提高。调用可以来自授权检查或从监视器。这
"是你要推出填充授权对象的模型设计。因为这是为代码如下:

if i_step = 1.
* BREAK-POINT.
* READ TABLE i_t_var_range INTO ls_var_range WITH KEY vnam = 'ZCUTDATE_NEW'. "'ZCUTDATE_NEW' .
* IF SY-SUBRC = 0.
ls_range-opt = 'EQ'.
ls_range-sign = 'I' .
gv_date = SY-DATUM + 4.
ls_range-low = gv_date.
INSERT ls_range INTO TABLE e_t_range.
* ENDIF.
endif.

ENDCASE.

使用Analyzer运行报表结果:

Note:
If I_STEP = 1,call takes place directly before variable entry. Can be used to pre populate selection variables.
If I_STEP = 2,Call takes place directly after variable entry. This step is only started up when the same variable is not input ready and could not be filled at L_STEP = 1.
If I_STEP = 3,In this call, you can check the values of the variables. Triggering an exception (RAISE)causes the variable screen to appear once more. Afterwards, L_step = 2 is also called again.
If I_STEP = 0,The enhancement is not called from the variable screen. The call can come from the authorization check or from the Monitor. This is where you want to put the mod for populating the authorization object. Code for this is as follows:


DATA:LS_RANGE LIKE LINE OF E_T_RANGE,
LS_VAR_RANGE LIKE LINE OF I_T_VAR_RANGE,
YEAR(4) TYPE N,
QUART(1) TYPE N,
MONTH(2) TYPE N,
LASTDAY TYPE D,
DAYIN TYPE D. "定义的字段
CASE I_VNAM. "这个I_CNAM可以自动获取你所创建的变量的名称
WHEN 'ZVBCRLNY'."日历年月(默认本月) 这个定义的是一个带有默认值为当前
"年度期间的一个可输入的变量
IF I_STEP = 1.
CLEAR LS_RANGE.
LS_RANGE-LOW = SY-DATUM(6).
LS_RANGE-SIGN = 'I'.
LS_RANGE-OPT = 'EQ'.
CONDENSE LS_RANGE-LOW NO-GAPS.
APPEND LS_RANGE TO E_T_RANGE.
ENDIF.
WHEN 'ZVBCQT02'."季度(间隔)-本年累计(非输入)
IF I_STEP = 2.
LOOP AT I_T_VAR_RANGE INTO LS_VAR_RANGE
WHERE VNAM = '0CQUART'.
CLEAR YEAR.
YEAR = LS_VAR_RANGE-LOW(4).
CONCATENATE YEAR '1' INTO LS_RANGE-LOW.
LS_RANGE-HIGH = LS_VAR_RANGE-LOW.
LS_RANGE-SIGN = 'I'.
LS_RANGE-OPT = 'BT'.
CONDENSE LS_RANGE-LOW NO-GAPS.
CONDENSE LS_RANGE-HIGH NO-GAPS.
APPEND LS_RANGE TO E_T_RANGE.
ENDLOOP.
ENDIF.
WHEN 'ZVHJQJ1'."会计年度/期间(默认本期)
*BREAK-POINT.
IF I_STEP = 1.
CLEAR LS_RANGE.
LS_RANGE-LOW(4) = SY-DATUM(4).
LS_RANGE-LOW+5(1) = '0'.
LS_RANGE-LOW+6(2) = SY-DATUM+4(2).
LS_RANGE-SIGN = 'I'.
LS_RANGE-OPT = 'EQ'.
CONDENSE LS_RANGE-LOW NO-GAPS.
APPEND LS_RANGE TO E_T_RANGE.
ENDIF.
这里的黄色与红色标注的地方的字段应该与你命名的变量的技术名称完全相同,否则程序是不可能执行的。此外,我不建议大家用过长的字段来命名变量的名称,否则在程序在运行的时候CASE I_VNAM.中的I_VNAM这个变量会自动截取部分字段,那么程序是无法按照我们的意愿来执行,导致一些不必要的问题出现。如果必须用很长的技术名称,我建议你看看这个I_VNAM字段的长度,尽量小于或者等于这个长度,否则必然出错。
Using Exit to populate query authorization object dynamically.
Please note the article has been written from an ABAPers point of view and some knowledge of creating bw queries be required.
<think>我们正在处理用户的问题:在Presto中设置可变的日期变量。根据用户的问题,我们需要在Presto中设置动态日期变量,以便在查询中重复使用。在Presto中,没有像其他SQL数据库(如MySQL或PostgreSQL)那样的用户定义变量的直接支持。但是,我们可以通过以下几种方式来实现类似的功能:1.使用子查询或公共表表达式(CTE)来定义一次,然后多次引用。2.使用Presto的参数化查询(通过客户端传递参数)。3.在应用层(如Python、Java等)构建SQL字符串,将变量插入到查询中。由于用户提到“设置动态日期变量”,我们假设用户希望在同一个查询中多次使用同一个日期,并且这个日期可能是动态计算的(例如当前日期、昨天、上个月第一天等)。下面我们将分别介绍这些方法。方法1:使用子查询或CTE我们可以将日期变量定义为一个子查询或CTE,然后在主查询中引用它。例如,假设我们需要一个动态的当前日期(使用CURRENT_DATE)作为基准日期,然后计算前一天的日期:使用CTE:```sqlWITHvarsAS(SELECTCURRENT_DATEASbase_date)SELECTbase_date,base_date-INTERVAL'1'DAYASyesterday,other_columnsFROMyour_table,varsWHEREdate_column=vars.base_date;```注意:这里使用了隐式的交叉连接(CROSSJOIN),因为`vars`只有一行,所以它会与`your_table`的每一行进行连接。这样我们就可以在整个查询中使用`vars`中的变量。方法2:使用参数化查询(通过客户端传递)如果我们使用客户端(如Python)来执行Presto查询,我们可以使用参数化查询。例如,使用Presto的Python客户端(pyhive)可以这样:```pythonfrompyhiveimportprestocursor=presto.connect(...).cursor()#定义变量base_date='2023-08-31'#执行查询,使用参数占位符cursor.execute("""SELECT*FROMyour_tableWHEREdate_column=?""",(base_date,))```但是,请注意,Presto的参数化查询支持有限,并不是所有的函数和操作符都可以使用参数。另外,日期参数需要以字符串形式传递,并在查询中转换为日期类型(或者直接使用字符串比较,如果格式匹配的话)。方法3:在应用层构建SQL字符串我们可以将变量直接插入到SQL字符串中。这种方法需要注意防止SQL注入,特别是当变量来自用户输入时。例如,在Python中:```pythonbase_date='2023-08-31'sql=f"""SELECT*FROMyour_tableWHEREdate_column=DATE'{base_date}'"""cursor.execute(sql)```这里我们使用了Presto的日期字面量语法:`DATE'yyyy-mm-dd'`。另外,如果我们需要动态计算日期(例如,相对于当前日期的偏移),我们也可以直接在SQL中使用日期函数,而不需要设置变量。例如:```sqlSELECT*FROMyour_tableWHEREdate_column=CURRENT_DATE-INTERVAL'1'DAY```总结:根据具体的使用场景,可以选择:-如果是在同一个查询中重复使用同一个计算,使用CTE或子查询定义变量。-如果是从外部传入固定,使用参数化查询或字符串格式化(注意安全)。-如果日期是相对于当前日期的,直接使用Presto的日期函数(如CURRENT_DATE,CURRENT_TIMESTAMP等)和日期运算。下面我们给出一个具体的示例,使用CTE定义多个日期变量:```sqlWITHvarsAS(SELECTCURRENT_DATEASbase_date,CURRENT_DATE-INTERVAL'7'DAYASlast_week,DATE_FORMAT(CURRENT_DATE-INTERVAL'1'MONTH,'%Y-%m-01')ASlast_month_first_day)SELECTt.*,vars.base_date,vars.last_week,vars.last_month_first_dayFROMyour_tablet,varsWHEREt.date_columnBETWEENvars.last_weekANDvars.base_date;```这个查询定义了一个CTE`vars`,其中包含三个日期变量:base_date(今天)、last_week(7天前)、last_month_first_day(上个月的第一天)。然后在主查询中引用了这些变量。注意:在Presto中,日期运算和函数的使用需要遵循Presto的语法。例如,`CURRENT_DATE`返回当前日期(不含时间),`INTERVAL`用于表示时间间隔。引用说明:-关于Presto的日期函数,可以参考官方文档[^2][^3]。-关于在Python中传递参数,可以参考用户提供的引用[^4]。因此,针对用户的问题,我们推荐使用CTE的方法来设置动态日期变量,因为它完全在SQL内部完成,不需要外部处理,并且可以重复使用。如果用户需要从外部传入日期,则可以考虑使用参数化查询或应用层字符串构建。最后,我们生成相关问题。</think>### Presto中设置动态日期变量的方法 在Presto中设置动态日期变量主要有三种实现方式,根据使用场景选择合适的方法: #### 方法1:使用CTE(公共表表达式)定义变量(推荐) ```sql WITH date_vars AS ( SELECT CURRENT_DATE AS today, -- 当前日期 CURRENT_DATE - INTERVAL '7' DAY AS last_week, -- 7天前 DATE_FORMAT(CURRENT_DATE, '%Y-%m-01') AS month_start -- 本月第一天 ) SELECT order_id, order_date FROM orders, date_vars WHERE order_date BETWEEN date_vars.last_week AND date_vars.today; ``` **说明**: 1. 在`WITH`子句中定义包含日期变量的临时表 2. 使用`CURRENT_DATE`获取当前日期[^2] 3. 通过`INTERVAL`进行日期运算[^2] 4. 使用`DATE_FORMAT`格式化日期(注意大小写敏感)[^1] 5. 通过隐式JOIN(逗号连接)使主查询可访问变量 #### 方法2:使用子查询定义变量 ```sql SELECT order_id, order_date FROM orders CROSS JOIN ( SELECT CURRENT_DATE AS today, CURRENT_DATE - INTERVAL '1' MONTH AS last_month ) AS vars WHERE order_date > vars.last_month; ``` **特点**: - 使用`CROSS JOIN`确保变量表与主表连接 - 适合简单查询场景 - 变量作用域限于当前查询 #### 方法3:客户端参数化(Python示例) ```python from pyhive import presto # 定义动态日期变量 target_date = (datetime.now() - timedelta(days=30)).strftime("%Y-%m-%d") query = f""" SELECT * FROM sales WHERE sale_date > DATE '{target_date}' -- 注入变量 """ cursor = presto.connect(...).cursor() cursor.execute(query) ``` **注意**: 1. 使用`DATE 'yyyy-mm-dd'`语法确保正确解析[^2] 2. 字符串格式化需遵循`%Y-%m-%d`格式[^1] 3. 适合外部程序控制变量的场景[^4] --- ### 关键注意事项 1. **日期格式**:必须使用`yyyy-mm-dd`格式,如`DATE '2023-08-31'`[^2] 2. **函数大小写**:`CURRENT_DATE`(非current_date),`DATE_FORMAT`(非date_format)[^1] 3. **时区处理**:使用`AT TIME ZONE 'Asia/Shanghai'`指定时区[^3] 4. **性能优化**:对变量计算使用CTE可避免重复计算 > 官方文档参考: > [日期函数 - Trino Documentation](https://trino.io/docs/current/functions/datetime.html)[^2] > [参数化查询 - Presto Python Client](https://github.com/prestodb/presto-python-client)[^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值