Ruby 通过Oracle DB连接时调用表中的列名称

Ruby 通过Oracle DB连接时调用表中的列名称,ruby,oracle,tsql,activerecord,oci8,Ruby,Oracle,Tsql,Activerecord,Oci8,我试图通过连接从表(employee)中获取值 oracle数据库。因为一列中有100个值,所以我需要迭代该表并获得准确的值 如果我使用索引号,比如第[1]行,那么我就有了可以使用的代码 希望使用列名称“first name”而不是行[1]。下面是 我拥有的代码是有效的。 代码: def load_borrower connection = OCI8.new('usrname', 'pwd', //host:portno/sid') connection.exec(("SELECT BI_

我试图通过连接从表(employee)中获取值 oracle数据库。因为一列中有100个值,所以我需要迭代该表并获得准确的值

如果我使用索引号,比如第[1]行,那么我就有了可以使用的代码 希望使用列名称“first name”而不是行[1]。下面是 我拥有的代码是有效的。 代码:

def load_borrower

connection = OCI8.new('usrname', 'pwd', //host:portno/sid') 

connection.exec(("SELECT BI_PREFIX, BI_FNAME, BI_MNAME, BI_LNAME, B.BI_SUFFIX, BI_ID_TYPE, BI_ID_NUMBER, BI_DOB,    B1.*, R.*, M.*, C.*, L.* FROM EMPLOYEE, SC_BORROWERPREF_NEW S1, BORROWER_NEW B, BORROWERPREF_NEW B1, RES_ADD R, MAIL_ADD M, CLOS_ADD C, LLORD_ADD L WHERE S2=SCENARIO_ID = S1.SCENARIO_ID AND S1.PREF_ID = B1.PREF_ID AND B1.BORROWER_ID = B.BORROWER_ID AND B1.PREF_ID = R.RES_PREF_ID AND B1.PREF_ID = M.MAIL_PREF_ID AND B1.PREF_ID = C.CLOS_PREF_ID AND B1.PREF_ID = L.LLORD_PREF_ID  AND S.RELEASE_ID= "1" AND S.SCENARIO_NO = '2' ORDER BY S1.SC_BORROWERPREF_ID") do |row|

$BI_PREFIX=row[0].to_s

$BI_FNAME=row[1].to_s

$BI_MNAME=row[2].to_s

$BI_LNAME=row[3].to_s

$BI_SUFFIX=row[4].to_s

$BI_BI_ID_TYPE=row[5].to_s

$BI_BI_ID_NUMBER=row[6].to_s

$BI_DOB=row[7].to_s

$BI_EMAIL=row[9].to_s

$BI_CELL_PH=row[11].to_s

$BI_WORK_PH=row[12].to_s

$BI_PREF_CONT=row[13].to_s

$BI_MAR_STATUS=row[16].to_s

$BI_EMP_STATUS=row[23].to_s

$BI_EDUC_YEARS=row[17].to_s

$BI_NUM_DEPEND=row[21].to_s

end

end
现在我正在运行下面的上述函数

load_borrower
因此,上面的代码现在运行良好。但正如您从上面看到的,我将db表中的变量定义为第[5]行、第[24]行,这非常繁忙和耗时,尽管它可以工作。所以我只是想知道我们是否有任何方法或命令使用列名,这样它就可以从行和列中获取值,比如行['Emp\u id'],而不是查找每个列名的索引


我不确定这是否是Ruby的一个缺点,因为它将db中的表视为一个数组,这可能就是我们不能按列名指定的原因。

如果您有一个包含列名的数组,那么您可以使用行数组将其压缩并构建哈希:

Hash[column_names.zip( row )]

不过,我建议您使用activerecord。

首先,您似乎对所使用的各种技术之间的界限和分离感到有点困惑。您提供的代码中没有Watir,无。这都是纯红宝石和一点点来自OCI8宝石的东西。GEM是Ruby用户用来分发用Ruby语言编写的代码库和程序的标准方式。有关更多信息,请参阅,以更好地了解什么是宝石以及如何使用它们

Watir是另一个用于驱动web浏览器的Ruby gem,您可能在代码的其他地方使用它,但它与这个问题或OCI8无关,它们都是作为gem分发的Ruby代码库。所以,让我们把它放在一边,以免混淆

您看到的行为是OCI8 gem的工作方式,与Ruby无关。如果您想要更优雅的东西,那么可以看看为使用Ruby进行db访问而创建的不同gem,例如ActiveRecord,这已经在另一个答案中提出了。OCI8 Gem仅在将结果馈送到块中时返回数组,就像在当前代码中一样。否则,结果在一个称为游标的对象中,您可以使用游标的fetch_hash方法将获取的数据作为散列。散列键是列名。(见附件)

请允许我强烈建议在深入研究当前项目之前,先花一点时间学习一下Ruby语言。考虑到您似乎正在进行的编码的性质,我建议您阅读Brian Marik的《使用Ruby编写日常脚本》一书,这将让您更好地理解您正在使用的技术,并且当我们像我刚才那样反复使用诸如“哈希”之类的术语时,您会更好地理解

如果您愿意就如何与数据库交互提供一些一般性建议。IMHO,您应该通过构造一个只返回所需数据的查询来利用数据库,而不是获取大量数据并尝试手动解析。它可以更好地利用资源,使用更少的内存,从数据库传输信息所需的时间更少,而且无论您的解析代码有多好,都不会像Oracle人员编写的那样好。让db来做这件事,这就是它的目的

如果您在这里处理的是驱动测试或验证结果的数据,而不是构建一个巨大的单片阵列,我建议您使用更模块化的方法。使用一个全局变量,例如您正在测试的当前用户的EMP_ID,并让测试代码仅获取每次验证所需的值的查询结果,或一个小的验证逻辑组,如地址的部分。以这种方式在逐案工作的基础上构建内容要容易得多,而不是试图将整个数据检索位写在一个巨大的片段中,这将是一场噩梦

就目前情况而言,所有验证功能或验证站点工作方式的测试代码都将紧密耦合到一个从数据库获取数据的大型单片。这会产生很多依赖关系,并使测试代码难以维护。如果您以一种更模块化的方式处理事情,其中每个验证步骤只检索它所需的数据,那么随着站点或数据库的更改,扩展或修改测试代码就会容易得多

这应该行得通

connection = OCI8.new('usrname', 'pwd', //host:portno/sid') 

cursor = connection.exec(("SELECT BI_PREFIX ...")
cols = cursor.get_col_names

while r = cursor.fetch
  $BI_PREFIX=r[cols.index('BI_PREFIX')].to_s
  ...
end

请尝试
row.EMP_ID
row.EMP_ID
?我看不到您的代码中调用了任何Watir方法,所以我不明白为什么这个问题有一个Watir标记。@zabba:row.EMP_ID不起作用,因为它给出了一个方法错误。基本上,这个问题与Watir无关,而是关于使用RUBY访问Oracle数据库的问题。。包含其他代码只会增加阅读量并混淆问题。(坦白地说,我认为如果有人能把问题还原到我们刚刚有代码试图访问数据库的地方,我们会过得更好)好的,Chuck,我已经删除了其他代码,而不是访问oracle数据库的代码。谢谢。唉,你那样做只会让事情变得更混乱。瓦蒂尔和你的问题没有任何关系。没错,恰克,但我用ruby来回答瓦蒂尔,所以这有点关联。既然你想要watir密码,我就把它放进去了。阅读这个问题的人可能会理解我真正想说的。因为我使用的是oci8 gem,这是watir的gem之一,我想我会从那些在watir中使用oci8 gem并通过列名称访问db的人那里得到帮助。顺便说一句,我还没有开始在我的项目中使用Ruby或Watir。我们现在是L