Oracle 如何在使用列时修改列数据类型
我在使用SELECT查询时遇到问题。不幸的是,Oracle 如何在使用列时修改列数据类型,oracle,function,plsql,Oracle,Function,Plsql,我在使用SELECT查询时遇到问题。不幸的是,ID被存储为VARCHAR,这是一个很大的错误,现在我在下面的函数中遇到了问题 FUNCTION GET_SUB_PROJECTS(p_currentUserId IN VARCHAR,p_projectId IN INT) RETURN SYS_REFCURSOR IS rc SYS_REFCURSOR; -- getSubProject BEGIN OPEN rc FOR SELECT p.*,
ID
被存储为VARCHAR
,这是一个很大的错误,现在我在下面的函数中遇到了问题
FUNCTION GET_SUB_PROJECTS(p_currentUserId IN VARCHAR,p_projectId IN INT)
RETURN SYS_REFCURSOR IS
rc SYS_REFCURSOR;
-- getSubProject
BEGIN
OPEN rc FOR
SELECT
p.*,
a.number_ AS activityNumber,
a.description AS activityDescription
FROM
projects p
LEFT JOIN
project_users_schedule_dates pusd
ON
pusd.ProjectID = p.ProjectID AND pusd.UserID = p_currentUserId
LEFT JOIN
activities a
ON
a.id = p.activity
LEFT JOIN
responsible_persons rp
ON
rp.ProjectID = p.ProjectID AND rp.UserID = p_currentUserId
LEFT JOIN
users u
ON
u.UserID = p_currentUserId
WHERE
(u.User_roleID = 1 AND
p.CustomName LIKE CONCAT((SELECT CustomName FROM projects pr WHERE pr.ProjectID = p_projectId), '%') AND p.ProjectID <> p_projectId)
OR
((
(p.Responsible_person_id = p_currentUserId OR p.Delivery_contact = p_currentUserId OR rp.UserID = p_currentUserId OR (pusd.UserID = p_currentUserId AND SYSTIMESTAMP BETWEEN TO_DATE(pusd.StartDate,'YYYY-MM-DD') AND TO_DATE(pusd.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY AND
SYSTIMESTAMP BETWEEN TO_DATE(p.StartDate,'YYYY-MM-DD') AND TO_DATE(p.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY))
)
AND
p.CustomName LIKE CONCAT((SELECT CustomName FROM projects pr WHERE pr.ProjectID = p_projectId), '%') AND p.ProjectID <> p_projectId)
ORDER BY p.CustomName;
RETURN rc;
END GET_SUB_PROJECTS;
我找到了一个可以修改的解决方案,但它给我带来了类似这样的错误
Error report -
ORA-01439: column to be modified must be empty to change datatype
01439. 00000 - "column to be modified must be empty to change datatype"
在这种情况下该怎么办?解决此问题的最佳方法是什么?您可以使用dbms\u重新定义
create table t (
c1 varchar2(10)
primary key
);
create table t_new (
c1 number(10, 0)
primary key
);
insert into t values ( '1.0000' );
commit;
begin
dbms_redefinition.start_redef_table (
user, 't', 't_new',
col_mapping => 'to_number ( c1 ) c1',
options_flag => dbms_redefinition.cons_use_rowid
);
end;
/
exec dbms_redefinition.sync_interim_table ( user, 't', 't_new' );
exec dbms_redefinition.finish_redef_table ( user, 't', 't_new' );
desc t
Name Null? Type
C1 NOT NULL NUMBER(10)
select * from t;
C1
1
在此过程中,还可以选择自动复制约束、触发器、索引等。您可以使用dbms\u重新定义
create table t (
c1 varchar2(10)
primary key
);
create table t_new (
c1 number(10, 0)
primary key
);
insert into t values ( '1.0000' );
commit;
begin
dbms_redefinition.start_redef_table (
user, 't', 't_new',
col_mapping => 'to_number ( c1 ) c1',
options_flag => dbms_redefinition.cons_use_rowid
);
end;
/
exec dbms_redefinition.sync_interim_table ( user, 't', 't_new' );
exec dbms_redefinition.finish_redef_table ( user, 't', 't_new' );
desc t
Name Null? Type
C1 NOT NULL NUMBER(10)
select * from t;
C1
1
在此过程中,还可以选择自动复制约束、触发器、索引等。只需使用CTAS语句重新创建表格:
创建表格t2作为ID,从t
,然后将表格t2重命名为t
,如果您确定ID
列中根本包含数值。对不起,我不明白你的意思。请你再描述一下好吗。TNX您想要的是更改ID列的数据类型,不是吗?通过这种建议的方式,您可以更改为数字数据类型,而不会出现ORA-01439
错误。顺便说一句,将重命名语法替换为RENAME t2 to t
Yes,从VARCHAR更改为NUMBER@BarbarosÖzhan你能根据我的问题给出答案吗。因此,负责人Id必须是数字(10,0)和送货联系人。我将非常感激。只要使用CTAS语句重新创建表:创建表t2作为ID,从t
中选择数字(ID)作为ID,然后将表t2重命名为t
,如果您确定ID
列包含所有数值。对不起,我不明白您的意思。请你再描述一下好吗。TNX您想要的是更改ID列的数据类型,不是吗?通过这种建议的方式,您可以更改为数字数据类型,而不会出现ORA-01439
错误。顺便说一句,将重命名语法替换为RENAME t2 to t
Yes,从VARCHAR更改为NUMBER@BarbarosÖzhan你能根据我的问题给出答案吗。因此,负责人Id必须是数字(10,0)和送货联系人。我会非常感激的。