【问题标题】:How to modify column data-type while column is in used如何在使用列时修改列数据类型
【发布时间】:2020-10-14 11:56:32
【问题描述】:

我在使用 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.*,
         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;

当我调用函数时,它需要返回数据,但它没有。不知何故,这里 p.Responsible_person_idp.Delivery_contact 需要是 NUMBER 但不知何故它是 VARCHAR 当我调用函数时,我使用

SELECT PROJECT_PACKAGE.GET_SUB_PROJECTS('199',141) FROM DUAL

我找到了一种可以修改的解决方案,但它给我带来了类似的错误

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"

在这种情况下该怎么办?解决此问题的最佳方法是什么?

【问题讨论】:

  • 只需使用 CTAS 语句重新创建表:CREATE TABLE t2 AS SELECT TO_NUMBER(ID) AS ID, &lt;other cols&gt; FROM t,然后是 RENAME TABLE t2 TO t,如果您确定 ID 列完全包含数值。
  • 对不起,我不明白你的意思。你能不能描述得更好。 Tnx
  • 你想要的是改变ID列的数据类型,不是吗?这种建议的方式,您可以更改为数字数据类型而不会出现ORA-01439 错误。顺便说一句,将重命名语法替换为RENAME t2 TO t
  • 是的,从 VARCHAR 更改为 NUMBER
  • @BarbarosÖzhan 您能否根据我的问题发布答案。因此,Responsible_person_Id 也必须是 number(10,0) 和 Delivery_contact。非常感谢。

标签: oracle function plsql


【解决方案1】:

您可以使用dbms_redefinitionchange the data type of a column online

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 

在这个过程中也有自动复制约束、触发器、索引等的选项。

【讨论】:

    猜你喜欢
    • 2012-03-07
    • 2012-01-08
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    • 2017-03-23
    • 2019-08-23
    相关资源
    最近更新 更多