如何在PL / SQL块中将游标添加到过程中?

时间:2018-08-04 22:39:28

标签: sql plsql plsqldeveloper plsql-package

我需要创建一个过程,该过程接受一个人名字的首字母和最后一个字母,并返回该人购买的总费用和全部物品。我不知道如何使用游标,我也在想必须使用for循环和异常处理,因为可能有很多人的起始字母和结尾字母都相同。

到目前为止,我已经提出了这个建议:

from __future__ import division
import smbus
import math
import time
import numpy as np
import matplotlib.pyplot as plt
import pygame
from threading import Thread
import multiprocessing
from queue import Queue
# Import the PCA9685 module.
import Adafruit_PCA9685


# Alternatively specify a different address and/or bus:
pwm = Adafruit_PCA9685.PCA9685(0x40) # pca9685 I2C Address

bus = smbus.SMBus(1)
address = 0x68 #MPU6050 I2C adress

# +++++++++++++++++++++++++++ Configurations ++++++++++++++++++++++++++++

# Configure min and max servo pulse lengths
servo_min = 250  # Min pulse length out of 4096 ---> 150
servo_max = 500# Max pulse length out of 4096 ----> 600
#calibration part
x_min_old =   -88.97162532327404
x_max_old =   483.97162532327417
y_min_old =   99.99999999999997
y_max_old =   329.17730025861925

OldRange_x= (x_max_old-x_min_old)
NewRange_x = (servo_max - servo_min)
OldRange_y = (y_max_old- y_min_old)  
NewRange_y = (servo_max- servo_min)

coords = 150, 150
angle = 70
radius1 = 5
radius2 =2

# ++++++++ mpu6050 configurations +++++++
power_mgmt_1 = 0x6b
power_mgmt_2 = 0x6c

#+++++++++++++++++ functions for mpu6050 +++++++++++++++++++++

def read_byte(adr):
 return bus.read_byte_data(address, adr)

def read_word(adr):
 high = bus.read_byte_data(address, adr)
 low = bus.read_byte_data(address, adr+1)
 val = (high << 8) + low
 return val

def read_word_2c(adr):
 val = read_word(adr)
 if (val >= 0x8000):
    return -((65535 - val) + 1)
 else:

     return val

def norm ():
    while True:
        accel_xout = read_word_2c(0x3b)
    #accel_yout = read_word_2c(0x3d)
        accel_zout = read_word_2c(0x3f)

        accel_xout_scaled = (accel_xout / 2048.0)
    #accel_yout_scaled = accel_yout / 2048.0
        accel_zout_scaled = (accel_zout / 2048.0)

        norm = np.sqrt(np.multiply(accel_xout_scaled,accel_xout_scaled)+np.multiply(accel_zout_scaled,accel_zout_scaled ))

        if (norm>10):
            q.put(norm)

        else:
            q.put(None)

    return  



#+++++++++++++++++ functions for pca9685+++++++++++++++++++++

# Helper function to make setting a servo pulse width simpler.
def set_servo_pulse(channel, pulse):
    pulse_length = 1000000    # 1,000,000 us per second
    pulse_length //= 60       # 60 Hz
    print('{0}us per period'.format(pulse_length))
    pulse_length //= 4096     # 12 bits of resolution
    print('{0}us per bit'.format(pulse_length))
    pulse *= 1000
    pulse //= pulse_length
    pwm.set_pwm(channel, 0, pulse)

# Set frequency to 60hz, good for servos.
pwm.set_pwm_freq(60) 

#function for the ellipse 
def move_coords(angle, radius1, radius2, coords):
    #def move_coords(angle, radius1, radius2, coords):
    theta = math.radians(angle)
    theta2 = math.radians(angle+20)
    x=coords[0] + radius1 * math.cos(theta)
    y=coords[1] + radius2 * math.sin(theta)
    return x, y



def searching():
    coords = 150, 150
    angle = 70
    radius1 = 5
    radius2 =2
    speed = 0.1
    next_tick = 1000
    clock = pygame.time.Clock()
    while True:        
          t=q.get()

          ticks = pygame.time.get_ticks()
          if t is None:
              if ticks > next_tick:
                 next_tick += speed
                 angle += 1
                 coords = move_coords(angle, radius1,radius2, coords)
                 x_old =coords[0]
                 y_old =coords[1]
                 NewValue_x = (((x_old- x_min_old) * NewRange_x) / OldRange_x) +servo_min  
                 NewValue_y = (((y_old - y_min_old) * NewRange_y) / OldRange_y) + servo_min 
                 x=  int(round(NewValue_x))
                 y=  int(round(NewValue_y))
                #print('x=' , x,'y=' , y )
                #print(coords)
                 pwm.set_pwm(0, 0, x)
                 pwm.set_pwm(2, 0, y)

          else:
              print('Motors stopped')
              break
    clock.tick(1000)

    return



#++++++++++++++++++++main loops ++++++++++++++++++++++++++++



#MPU6050 ilk calistiginda uyku modunda oldugundan, calistirmak icin asagidaki komutu veriyoruz:
bus.write_byte_data(address, power_mgmt_1, 0)

if __name__=="__main__":
    print ("Data reading start ")
    q=Queue()
    sensor= Thread(target=norm)
    motors= Thread (target = searching)
    sensor.start()
    motors.start()

1 个答案:

答案 0 :(得分:0)

想出一种解决方案,只需稍作修改(顺便说一下,对参数名称要更具体一点,那就是没有解释):

procedure total_spent(
  p_fname_first_letter in varchar2,
  p_lname_last_letter in varchar2,
  p_netspend out number,
  p_totalpurch out number) as

  cursor c_net(
    p_fname_first_letter varchar2,
    p_lname_last_letter varchar2) is
  select
    sai.cname, 
    sum(sai.net + sai.tax) net_spend,
    count(sai.net) total_purch 
  from 
    saleinv sai
  where 
    upper(sai.cname) like upper(p_fname_first_letter) || '%' || upper(p_lname_last_letter)
  group by
    sai.cname;

  l_found_cust boolean := false;
  l_show_err boolean := false;
  l_cust_list varchar2(100);

Begin

  p_netspend := 0;
  p_totalpurch := 0;

  for l_sai_rec in c_net(
    p_fname_first_letter,
    p_lname_last_letter)
  loop

    if not l_found_cust then

      p_netspend := l_sai_rec.net_spend;
      p_totalpurch := l_sai_rec.total_purch;
      l_cust_list := l_sai_rec.cname;
      l_found_cust := true;

    else

      l_cust_list := l_cust_list || '; ' || l_sai_rec.cname;
      l_show_err := true;

    end if;

  end loop; 

  if l_show_err then
    raise_application_error(-20101, 'Found more customers with provided parameters. Customers: '||l_cust_list);
  end if;

end;

如上所述,它使用光标。当然,没有游标,还有更好的方法可以满足您的逻辑要求(更少的代码)。如果您愿意知道,请随时提问。