Ruby 粘合剂
SQL 对于在 Oracle 数据库中操作数据集很有用。Shell 脚本(包含 Linux 命令)在文件系统级别工作良好。如果需要在数据库内部和外部操作数据集,可以执行哪些操作?
Ruby 可以充当“粘合剂”语言,促进独立技术或应用程序层之间的通讯。此功能的一个示例是,使用 Ruby 提供数据库与操作系统之间的交互。考虑 web 应用程序中一个相当普遍的情况:即,数据库中的一个记录包含对文件系统上某个文件的引用。例如,一个用户上载了图片,随后使用该用户的 id 将该图片保存到文件系统。如果您需要确定哪个用户(了解具体名称)上载了文件,需要使用一个衔接这两个领域的解决方案。
除了 Ruby 之外,这些示例还需要一些额外安装。在运行以下示例之前,还应该安装 Oracle Client(连同配置好的、到包含 HR 模式的 Oracle 数据库 [如 Oracle 数据库快捷版] 的连接)和 OCI8 gem (ruby-oci9)(参见页面顶部的“下载”部分)。
首先,导航到将在其中创建文件的目录,以模拟该情景。您可以在 irb 中逐行输入以下程序,或者在包含先前创建的文件的目录中,将整个清单保存到一个文件中,然后在命令行执行它(ruby <文件名>)。清单中的注释行前面有一个 # 符号:
# First, enter some preliminary commands to create files that will
# simulate data that was uploaded by users. Load the OCI8 package
# and make a connection to your database:
require 'OCI8'
conn =OCI8.new('hr', 'hr', 'xe')
# Next create a SQL query that will return all of the users
# that have an "a" in their last name.
# This simulates arbitrary user uploaded files:
sql="select employee_id||'_'||upper(last_name)|| '.gif' "
sql+="from employees where upper(last_name) like '%A%'"
# Now we will create the actual (empty) files.
# They will be named using the employee id and last name.
# as specified in the first (and only) field in the query
conn.exec(sql) { |r| File.new(r[0],'w') }
如果您在 irb 中运行了这些示例,可以在提示符下键入“exit”,然后查看已创建的文件。
| # Load OCI8 require 'OCI8' # Make a connection to the Oracle Database containing the HR sample schema conn =OCI8.new('hr', 'hr', 'xe') # Create a SQL query sql="select employee_id||'_'||upper(last_name)|| '.gif'," sql+=" last_name, first_name from employees order by 2,3" # Execute the query. Each result is an array of strings representing # each field in the query. If a file exists on the file system that matches # the pattern we specified earlier, display an X conn.exec(sql) do |r| if File.exists?(r[0]) print 'X ' else print ' ' end # Display the last name followed by the first name puts "#{r[1]}, #{r[2]}" end |
该报告的结果将写入标准输出,应与以下内容类似:
X Abel, Ellen
X Ande, Sundar
X Atkinson, Mozhe
X Austin, David
X Baer, Hermann
X Baida, Shelli
X Banda, Amit
X Bates, Elizabeth
Bell, Sarah
Bernstein, David
Bissot, Laura
Bloom, Harrison
Bull, Alexis
X Cabrio, Anthony
...
Weiss, Matthew
X Whalen, Jennifer
Zlotkey, Eleni
注意,(按照预期)应该只列出姓氏中包含“a”并且名称前包含“X”(表示存在关联文件)的用户。
Oracle 提供了许多完全在数据库中处理该情况的方法。例如,可以使用 BLOB 在数据库本身内将图像作为二进制数据存储。然而,如果该设计不适用,这也有助于用户了解其他一些替代方法。
在下面的表中,每种情况的数据来源不同,但处理方法类似。SQL 数据集是针对数据库表的查询结果。Linux 数据集是传送到所列出命令的某个命令的结果。上面所述的 Ruby 示例的数据集是一个 Ruby 字符串数组。表达式均具有代表性;根据所讨论的数据集,特定值将有所不同。
| SQL | Linux 命令 | Ruby | 说明 |
| WHERE col1 = 'value' | grep value | myArr.grep('value') | 限制结果,返回匹配项 |
| WHERE col1 != 'value' | grep -v value | MyArr.– myArr.grep('value') | 限制结果,返回不匹配的项 |
| ORDER BY 1 | sort | myArr.sort | 按序排列结果 |
| SELECT DISTINCT col1 | uniq field1 | myArr.uniq | 从结果中删除重复项 |
| SELECT COUNT(*) , col1 FROM y GROUP BY x | sort | uniq -c | myArr.uniq.size | 找出在一组结果中存在多少给定结果 |
| SELECT col2, col1 | awk '{print $2 "\t" $1}' | myArr.each{|rec| puts "#{rec[1,2]} #{rec[0,1]}"} | 将结果限制为给定结果数据行的特定部分 |

