首页 \ 问答 \ 作为另一个用户执行Oracle存储过程(Executing an Oracle Stored Proc as Another User)

作为另一个用户执行Oracle存储过程(Executing an Oracle Stored Proc as Another User)

我主要是甲骨文新手,所以如果这是一个愚蠢的问题,请原谅我...

我有一个名为'CODE'的架构,其中包含一个执行任意SQL的存储过程(现在,请忽略与此相关的潜在安全问题)。 传入的SQL将选择数据; 但所有数据都驻留在模式A,B或C中 - 但SQL一次只能从一个模式中选择。

例如:类型A的用户创建一个字符串'SELECT * FROM A.USERTABLE' - 类型B的用户创建一个字符串'SELECT * FROM B.USERTABLE'。

我想要做的是让用户不显式指定他们的模式。 在前端.net应用程序中; 我已经知道他们是A型,B型还是C型。我希望所有三个人都简单地输入'SELECT * FROM USERTABLE'。

我遇到的问题是我不知道该怎么做。 我的应用程序只能在'CODE'模式下执行proc,因此我不能只复制代码并让用户A调用'A.ExecuteSQL'。

我尝试了一些东西; 但到目前为止没有任何工作。 我希望ExecuteSQL过程保持在CODE模式中; 但是当'USERTABLE'通过时,我需要知道有时这意味着A.USERNAME,有时候B.USERNAME。

有什么建议么?


I'm mostly an oracle novice, so forgive me if this is a stupid question...

I have a schema called 'CODE' with a stored proc that executes arbitrary SQL (for now, please ignore the potential security issues associated with that). The SQL that is passed in will select data; but all of the data resides in either schema A, B, or C - but the SQL will only ever select from ONE schema at a time.

For example: User of type A creates a string 'SELECT * FROM A.USERTABLE' - while user of type B creates a string 'SELECT * FROM B.USERTABLE'.

What I'm trying to do is allow the user to not explicitly specify their schema. In the front-end .net application; I already know if they are type A, B, or C. I want all three to simply enter 'SELECT * FROM USERTABLE'.

The problem I'm having is that I don't know how to do that. My app can only execute proc in the 'CODE' schema - so I can't just duplicate the code and let user A call 'A.ExecuteSQL'.

I've tried a few things; but nothing has worked thus far. I want the ExecuteSQL proc to stay in the CODE schema; but when 'USERTABLE' gets passed in, I need it to know that sometimes that means A.USERNAME and sometimes B.USERNAME.

Any suggestions?


原文:https://stackoverflow.com/questions/2376664
更新时间:2022-02-12 16:02

最满意答案

关于我从JCIP获得的waitnotify的主要信息是我可能错误地使用它们,所以最好避免直接使用它们,除非严格必要。 因此,我认为您应该重新考虑使用这些方法。

在这种情况下,我认为您可以使用SynchronousQueue更优雅地完成它。 也许这样的事可能有用:

import java.util.concurrent.*;
public class RecursiveTotalFinder {
    public static void main(String... args) throws InterruptedException {
       SynchronousQueue<Integer> syncQueue = new SynchronousQueue<>();

       //Create object
       TotalFinder tf = new TotalFinder(syncQueue, 5);

       //Start the thread
       tf.start();

       for (int i = 0; i < 3; ++i) {
         System.out.println("Current total: " + syncQueue.take());
       }
    }
}

class TotalFinder extends Thread{
  private final SynchronousQueue<Integer> syncQueue;
  private final int syncEvery;
  private int count;

  public TotalFinder(SynchronousQueue<Integer> syncQueue, 
                     int syncEvery) {
    this.syncQueue = syncQueue;
    this.syncEvery = syncEvery;
  }

  public void run() {
    try {
      findTotal(16);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new RuntimeException(e);
    }
  }

  //Find total
  void findTotal(int cnt) throws InterruptedException {
    if((count > 0) && (count%syncEvery==0)) {
      syncQueue.put(count);
    }
    count +=1;
    if(count < cnt) {
      System.out.println(count +" < "+cnt);
      findTotal(cnt);
    }
  }
}

至于为什么你的原始方法不起作用,这是因为主线程将gotSignalFromMaster设置为true然后立即返回false ,这发生在另一个线程能够检查其值之前。 如果你在resetWaitLock保持一点睡眠,它会超出当前挂起的点; 然而,它然后挂起而不是终止。

请注意,必须使用Thread.sleep等待另一个线程更改某些状态是一种糟糕的方法 - 尤其是因为它会使您的程序变得非常慢。 使用同步实用程序可以更快,更容易理解程序。


The main message about wait and notify that I got from JCIP was that I'd probably use them wrongly, so better to avoid using them directly unless strictly necessary. As such, I think that you should reconsider the use of these methods.

In this case, I think that you can do it more elegantly using SynchronousQueue. Perhaps something like this might work:

import java.util.concurrent.*;
public class RecursiveTotalFinder {
    public static void main(String... args) throws InterruptedException {
       SynchronousQueue<Integer> syncQueue = new SynchronousQueue<>();

       //Create object
       TotalFinder tf = new TotalFinder(syncQueue, 5);

       //Start the thread
       tf.start();

       for (int i = 0; i < 3; ++i) {
         System.out.println("Current total: " + syncQueue.take());
       }
    }
}

class TotalFinder extends Thread{
  private final SynchronousQueue<Integer> syncQueue;
  private final int syncEvery;
  private int count;

  public TotalFinder(SynchronousQueue<Integer> syncQueue, 
                     int syncEvery) {
    this.syncQueue = syncQueue;
    this.syncEvery = syncEvery;
  }

  public void run() {
    try {
      findTotal(16);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new RuntimeException(e);
    }
  }

  //Find total
  void findTotal(int cnt) throws InterruptedException {
    if((count > 0) && (count%syncEvery==0)) {
      syncQueue.put(count);
    }
    count +=1;
    if(count < cnt) {
      System.out.println(count +" < "+cnt);
      findTotal(cnt);
    }
  }
}

As to why your original approach doesn't work, it's because the main thread sets gotSignalFromMaster to true and then immediately back to false, and this happens before the other thread is able to check its value. If you stick a bit of a sleep into the resetWaitLock, it proceeds beyond the point where it currently hangs; however, it then hangs at the end instead of terminating.

Note that having to use Thread.sleep to wait for another thread to change some state is a poor approach - not least because it makes your program really slow. Using synchronization utilities leads to faster and much easier-to-reason-about program.

相关问答

更多
  • 关于我从JCIP获得的wait和notify的主要信息是我可能错误地使用它们,所以最好避免直接使用它们,除非严格必要。 因此,我认为您应该重新考虑使用这些方法。 在这种情况下,我认为您可以使用SynchronousQueue更优雅地完成它。 也许这样的事可能有用: import java.util.concurrent.*; public class RecursiveTotalFinder { public static void main(String... args) throws Inter ...
  • CountDown锁存器经常用于您的示例的完全相反。 一般来说,在“await()”上会有很多线程阻塞,当countown到达零时,这些线程将同时启动。 final CountDownLatch countdown = new CountDownLatch(1); for (int i = 0; i < 10; ++ i){ Thread racecar = new Thread() { public void run() { countdown.await ...
  • 是的,你明白了。 CountDownLatch在锁定原理中工作,主线程将等到门打开。 一个线程在Java中创建CountDownLatch等待指定的n个线程数。 调用CountDownLatch.await()任何线程,通常是应用程序的主线程将等待直到计数达到零或被另一个线程中断。 所有其他线程必须在完成或准备好后调用CountDownLatch.countDown()才能倒计时。 一旦count达到零,Thread等待开始运行。 CountDownLatch一个缺点/优点是,一旦count达到零,就不能重 ...
  • 如果我是正确的,为什么没有任何机构在wait()和sleep()之间的区别中提到这一点 (你是对的。) 因为在两种情况下都是一样的并不是一个区别。 您已经联系的Q&A询问sleep和wait之间的差异 。 大概是因为你读到的具体答案的作者并不认为这与他们所说的相关。 或者因为他们认为这很明显。 另外,根据我的理解,当调用Thread.sleep(t)时,在时间t之后,生成中断信号以将此任务也用于下一个cpu周期。在object.wait()的情况下会发生什么? 是否也为object.wait()生成了中断? ...
  • 您可能想要考虑Brian Goetz撰写的文章: Java理论与实践:处理InterruptedException 一般情况下,如果您不知道该怎么做,那么除了让调用者代码知道在等待锁定时可以中断此方法时,不要做任何事情。 您可以通过将InterruptedException抛出到方法签名来执行此操作。 如果由于某种原因你被迫添加一个try / catch块并处理异常,那么Thread.currentThread()。interrupt()会做,但重新抛出它可能是合适的。 You might want to ...
  • 另一个线程需要obj上的锁才能调用obj.notify() 。 如果你的线程在while循环中没有等待,它就不能拥有它,因为你的线程还需要obj上的锁定在while循环中。 Another thread needs the lock on obj to be able to call obj.notify(). And it can't have it if your thread is in the while loop not waiting, since your thread also needs ...
  • 如果使用shutdownNow()和awaitTernimation(),这将中断所有正在运行的任务并等待它们完成。 如果任务可以被中断并在中断时关闭所有资源,那么应该没有问题。 (如果出现问题,这是您应该修复的任务代码中的错误) If you use shutdownNow() and awaitTernimation() this will interrupt all running tasks and wait for them to finish. Provided the tasks can be ...
  • wait / notify背后的想法是通知不是特定于线程的,通知程序不必知道需要通知的特定线程,它只是告诉锁定(或条件,对于ReentrantLock)它正在通知,并且他们之间的锁定和OS调度程序决定谁获得通知。 我希望通知程序大多数时候都不想知道哪个线程需要取消停放,所以wait / notify对于那些情况来说是更好的选择。 使用park / unpark,您的代码必须了解更多,并且会有更多失败的机会。 您可能认为同步块是单调乏味的,但真正繁琐的是整理出某些东西在它应该没有停放的情况。 请注意,在第二个 ...
  • 您的原始配置与Log(显式或继承)的所有方法匹配,包括Object#wait()。 它告诉ProGuard,wait()方法没有副作用,可以在不损害程序的情况下删除它。 你注意到这显然不是真的。 使用-assumenosideeffects时,您应该始终明确列出可以安全删除的方法。 Your original configuration matches all methods of Log (explicit or inherited), including Object#wait(). It tells ...
  • 只是为了充实我的评论: CompletionService service = new ExecutorCompletionService( Executors.newFixedThreadPool(nThreads)); for (Image image : images) { service.submit(new ImageRunnable(image), image); } try { for (int i = 0; i < images.size(); i++ ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)