比较两列并进行插入

时间:2014-11-11 12:32:24

标签: sql postgresql stored-procedures postgresql-9.1

我想比较两个来自两个不同表的列。

其中一个列,我需要为所有具有标识的行生成SUM,并且说3并存储到变量。 之后,与其他表中的一行比较相同的标识3,如果first_column< = second_column,则将ELSE插入BREAK。

有人可以建议一些查询吗?对于Postgresql ......

CREATE OR REPLACE FUNCTION "SA_PRJ".usp_add_timesheet_test(p_uid integer, p_project_id integer, p_allocated_time numeric, p_achieved_time numeric, p_task_desc character varying, p_obs character varying, p_date timestamp without time zone)
  RETURNS character varying AS
$BODY$
DECLARE sum_alloc_time numeric; 
DECLARE alloc_hours integer;
DECLARE fld_id integer;
DECLARE alloc_id integer;

BEGIN
   if not "SA_ADM".usp_check_permission(p_uid, 'SA_PRJ', 'usp_add_timesheet_record') then
    raise exception 'User ID % dont have permission!', p_uid;
   end if;

   select a.fld_id into alloc_id from "SD_PRJ".tbl_project_allocation a where a.fld_emp_id = p_uid and a.fld_project_id = p_project_id;

   SELECT SUM(fld_allocated_time)
   INTO           sum_alloc_time 
   FROM   "SD_PRJ".tbl_project_timesheet 
   WHERE  fld_project_id = p_project_id;

   SELECT p.fld_allocated_days, p.fld_id
   INTO            alloc_hours,   fld_id 
   FROM   "SD_PRJ".tbl_project p
   JOIN   "SD_PRJ".tbl_project_timesheet t USING (fld_id)
   WHERE  t.fld_project_id = p_project_id;

  IF @sum_alloc_time <= @alloc_hours THEN

  INSERT INTO "SD_PRJ".tbl_project_timesheet
    (fld_emp_id, fld_project_id, fld_is_allocated,   fld_allocated_time
   , fld_achieved_time, fld_task_desc, fld_obs, fld_date)
  VALUES (p_uid,   p_project_id, coalesce(alloc_id,0), p_allocated_time
     , p_achieved_time,   p_task_desc,   p_obs,   p_date);

     RAISE NOTICE 'INSERT OK!';

 ELSE
  RAISE NOTICE 'NOT OK';
 END IF;
END

1.tbl_project(fld_id,fld_allocated_days,fld_project_id)

2.tbl_project_timesheet(fld_id,fld_allocated_time,fld_project_id),所有INTEGER

我有这个,但是我按照自己的意愿工作。谢谢

1 个答案:

答案 0 :(得分:1)

我认为有一个问题在这里:

 SELECT p.fld_allocated_days, p.fld_id
   INTO            alloc_hours,   fld_id 
   FROM   "SD_PRJ".tbl_project p
   JOIN   "SD_PRJ".tbl_project_timesheet t USING (fld_id)
   WHERE  t.fld_project_id = p_project_id;

只要select查询返回多行,即只要tbl_project_timesheet有一个fld_id,project_id组合的多条记录,那就会咳嗽(我想)。

反正。这是一个部分简化的答案,但希望你能得到这个想法......

我不会使用局部变量。插入一步:

INSERT INTO timesheet(emp_id,project_id) -- other columns
SELECT 
    p_uid,p.fld_project_id -- other columns
FROM

    projects p

INNER JOIN
    (SELECT SUM(fld_allocated_time) as sumtime
        FROM timesheet t WHERE fld_project_id = p_project_id) as sumtime_subquery
ON p.fld_allocated_days < sumtime -- just join on the allocated time
WHERE p.fld_project_id = p_project_id;

现在,您需要知道是否实际插入了任何内容。我认为您可以使用RETURNING声明的INSERT选项,例如来自here(警告 - 我从未使用过RETURNING,也没有从with语句设置局部变量):

WITH ROWS AS (
 INSERT INTO timesheet(emp_id,project_id) -- other columns
    SELECT 
        p_uid,p.fld_project_id -- other columns
    FROM

        projects p

    INNER JOIN
        (SELECT SUM(fld_allocated_time) as sumtime
            FROM timesheet t WHERE fld_project_id = p_project_id) as sumtime_subquery
    ON p.fld_allocated_days < sumtime -- just join on the allocated time
    WHERE p.fld_project_id = p_project_id
    RETURNING 1
    )
    SELECT COUNT(*) into l_updatedCount FROM rows; -- you have to declare l_updatedCount

-- Now an if statement to handle l_updatedCount