我是PL SQL的新手并且还在学习,但我需要解决一个问题而且我不太了解PL SQL来快速解决我的问题.
我引用了两个表:用户和属性.我有一个带3个参数的过程:attrib_id,uid, attrib_value.
我首先使用attrib_id查询属性表以返回属性名称并将其分配给变量.我的代码到目前为止.
接下来,我想在另一个select语句中使用从前一个select语句创建的变量来查询users表,并返回与该变量所代表的属性关联的当前值.
码:
PROCEDURE value_update_proc_z(attrib_id INTEGER, uid IN VARCHAR2, attrib_value IN VARCHAR2)
IS
v_old_attrib_name attributes.attribute_name%TYPE;
v_oldattrib_value varchar2(100);
v_mymsg varchar2(2000);
BEGIN
EXECUTE IMMEDIATE 'SELECT attrib_name FROM attributes WHERE indx = ''' || attrib_id || '''' INTO v_old_attrib_name;
EXECUTE IMMEDIATE 'SELECT' || v_old_attrib_name || 'FROM USERS WHERE USERID = ''' || uid || '''' INTO v_oldattrib_value;
v_mymsg := v_old_attrib_name || ' ' || v_oldattrib_value;
END value_update_proc_z;
Run Code Online (Sandbox Code Playgroud)
第一个查询应该根据传递给过程的数字从属性表中返回一个值.例如,如果attrib_id …
对于我的作业,我需要创建一个包含一个过程的包,该过程从表dwdimartist中删除所有记录,然后用表格艺术家的所有记录填充表格,并添加一个具有今天日期的字段.
这就是我创造的,它有效,但我不知道它是否具有足够的性能.使用循环遍历表艺术家中每条记录的游标是否更好?
CREATE OR REPLACE PACKAGE BODY dwh AS
PROCEDURE filldwh IS
today_date DATE := SYSDATE;
BEGIN
DELETE FROM dwdimartist;
INSERT INTO dwdimartist (artistkey, name) (SELECT artistid, name FROM artist);
UPDATE dwdimartist SET added = today_date;
END filldwh;
END dwh;
Run Code Online (Sandbox Code Playgroud) 我在包内有以下程序:
PROCEDURE test1
IS
InsertST varchar2(32000) : = 'INSERT INTO tableA (col1, col2)
(select cola,
INITCAP(REPLACE(colX, '_', ''))
from tableB))';
Begin
execute immediate InsertST;
END
Run Code Online (Sandbox Code Playgroud)
在编译期间我收到错误:
错误(1177,45):PLS-00103:遇到以下其中一项时遇到符号"_":*&= - +; </> at in是mod的余数不是rem <>或!=或〜=> = <= <>和/或类似like2 like4 likec之间的|| 成员submultiset
东西是错误的"_"内部功能:INITCAP(REPLACE(colX, '_', ''))
怎么解决?也许是其他方式?
我在Oracle application Express 4.2中有一个SQL查询(PL/SQL函数体返回SQL查询).我创建了一个经典报告,这是我在下面使用的查询.我的查询当前工作正常但我需要使用另一个查询更新此函数中的现有查询,当我尝试更改查询时它不起作用.我究竟做错了什么?任何帮助表示赞赏.
以下是我的工作查询:
declare
a_query varchar2(5000);
this_strin varchar2(50);
begin
a_query := 'select flight_nmbr, sequence_nmbr '||
'from flights '||
'where sequence_nmbr >= 0 and data_version_name = ''' ||
:P3_DATA_VERSION || '''';
if :P3_SEARCH_NUMBER is not null then
if instr(:P3_SEARCH_NUMBER, '%') > 0 then
this_strin := :P3_SEARCH_NUMBER;
else
this_strin := '%'||:P3_SEARCH_NUMBER||'%';
end if;
a_query := a_query||chr(10)||
' and flight_nmbr like '''|| upper(this_strin) ||'''';
end if;
return a_query;
end;
Run Code Online (Sandbox Code Playgroud)
我需要将此函数内的查询更新为以下内容:
SELECT FLIGHT_NMBR, SCHEDULED_LAUNCH_DATE
FROM FLIGHTS
WHERE DATA_VERSION_NAME = 'WORKING' AND
sequence_nmbr …Run Code Online (Sandbox Code Playgroud) 以下函数检查名为ZIPCODE的表中是否存在邮政编码:
create or replace function zip_does_not_exist(i_zip in zipcode.zip%type)
return boolean
as
v_zip zipcode.zip%type;
begin
select zip into v_zip
from zipcode
where zip = i_zip;
if v_zip is not null then
return false;
else
return true;
end if;
end;
/
Run Code Online (Sandbox Code Playgroud)
为了测试这个函数,我发出了以下语句,该语句应该返回false,因为作为参数传递的邮政编码存在于ZIPCODE表中:
select zip_does_not_exist('00914') from dual;
Run Code Online (Sandbox Code Playgroud)
但是,我在尝试运行此代码时收到此消息:
Error report:
SQL Error: ORA-00902: invalid datatype
00902. 00000 - "invalid datatype"
*Cause:
*Action:
Run Code Online (Sandbox Code Playgroud)
这不应该发生,因为'00914'是作为参数所需的正确数据类型(varchar2(5)).我为什么收到这条消息?
我是pl/sql的新手.我正在尝试像这样的触发器(adr =删除行之后),但似乎我不能使用ALTER SEQUENCE.这是删除行之后递减的正确方法还是我应该使用过程?
CREATE OR REPLACE TRIGGER adr_trg
AFTER DELETE ON table
FOR EACH ROW
BEGIN
ALTER SEQUENCE table_seq INCREMENT BY -1;
END;
Run Code Online (Sandbox Code Playgroud)
编辑:
我正在使用的序列:
CREATE SEQUENCE table_seq INCREMENT BY 1 START WITH 1;
Run Code Online (Sandbox Code Playgroud)
触发我正在使用:
CREATE OR REPLACE TRIGGER bir_trg
BEFORE INSERT ON table
FOR EACH ROW
BEGIN
IF :new.id IS NULL
THEN
:new.id := table_seq.nextval;
END IF;
END bir_trg;
Run Code Online (Sandbox Code Playgroud) 我现在很困惑; 我正在编写一个脚本来查找用户正在进行的所有角色.这是一项正在进行中的工作,由于我对PLSQL缺乏了解,如果你知道我的意思,那么进展并不是很多.
-- Declaration of Table Type
create or replace TYPE TEST
AS TABLE OF VARCHAR(30);
-- Function here
create or replace FUNCTION FINDPARENTS
(
ROLENAME IN VARCHAR2
)
RETURN TEST
IS
tt_t TEST;
BEGIN
DECLARE
results test;
toadd test := TEST(ROLENAME);
counter number;
elements number:=1;
BEGIN
SELECT GRANTED_ROLE
BULK COLLECT INTO toadd
FROM DBA_ROLE_PRIVS
WHERE GRANTEE = rolename;
SELECT COUNT(*)
INTO ELEMENTS
FROM toadd; -- Error here.
--(for i in 0 .. ELEMENTS) SELECT FINDPARENTS(ROLE_NAME) FROM DUAL UNION RESULT …Run Code Online (Sandbox Code Playgroud) 我想取current date,week number,first date in the week和last date in the week.它下面的SQL语句正在工作,但是当我在Oracle Apex中运行时,我得到了ORA-01843: not a valid month
declare
date_value char;
week_value pls_integer;
start_date_value char;
end_date_value char;
begin
SELECT
TO_CHAR(TRUNC(TO_DATE(CURRENT_DATE,'MM/DD/YYYY')),'DD.MM.YYYY')
, TO_NUMBER(TO_CHAR(TO_DATE(CURRENT_DATE,'MM/DD/YYYY'),'WW'))
, TO_CHAR(TRUNC(TO_DATE(CURRENT_DATE,'MM/DD/YYYY'), 'IW'),'DD.MM.YYYY')
, TO_CHAR(NEXT_DAY(TRUNC(TO_DATE(CURRENT_DATE,'MM/DD/YYYY'),'IW'),'SUNDAY'),'DD.MM.YYYY')
INTO
date_value
, week_value
, start_date_value
, end_date_value
FROM DUAL;
htp.p('<< '||'Week'|| week_value ||' >> '|| start_date_value ||' - '|| end_date_value);
end;
Run Code Online (Sandbox Code Playgroud)
也尝试使用sysdate并且仅在SQL中有效但在PL/SQL(Oracle Apex)页面中抛出相同的异常.提前致谢.
UDF和SP之间的主要区别之一是UDF只能在其中包含select语句而不能插入/更新/删除语句.有人可以解释一下这背后的原因吗?以下功能:
create function test(..)
...
BEGIN
insert into EMPLOYEE('22',12000,'john');
return 0;
END
Run Code Online (Sandbox Code Playgroud)
无效.但为什么会这样呢?
当在KSH中针对Linux上的Oracle 11.2.0.4或更高版本的数据库通过SQLPLUS运行脚本时,是否可以检测DDL语句,退出并回滚所有以前的非DDL语句?所以这将是这样的,但增强了停止第一个DDL.
WHENEVER SQLERROR EXIT ROLLBACK
@script.sql
Run Code Online (Sandbox Code Playgroud)
有没有办法在PLSQL中设置异常处理,以便在第一个DDL语句执行之前立即退出?