我使用简单的Perl脚本连接到Oracle 11g数据库时出现以下错误:
failed: ERROR OCIEnvNlsCreate. Check ORACLE_HOME (Linux) env var or PATH (Windows) and or NLS settings, permissions, etc. at
Run Code Online (Sandbox Code Playgroud)
脚本如下:
#!/usr/local/bin/perl
use strict;
use DBI;
if ($#ARGV < 3) {
print "Usage: perl testDbAccess.pl dataBaseUser dataBasePassword SID dataBasePort\n";
exit 0;
}
my ($user, $pwd, $sid, $port) = @ARGV;
my $host = `hostname`;
my $dbh;
my $sth;
my $dbname = "dbi:Oracle:HOST=$host;SID=$sid;PORT=$port";
openDbConnection();
closeDbConnection();
sub openDbConnection() {
$dbh = DBI->connect ($dbname, $user ,$pwd , { RaiseError => 1}) || die "Database …Run Code Online (Sandbox Code Playgroud) 根据DBI文档,似乎我只能通过该do方法获得受影响的行数.
$rows_affected = $dbh->do("UPDATE your_table SET foo = foo + 1");
Run Code Online (Sandbox Code Playgroud)
如果我使用prepare/ execute?如何获得相同的结果?
编辑:据我所知,这个问题的根本原因是安装了正确的 Perl 模块,但mysql.so加载了错误的文件。
my $dsn = "DBI:mysql:"
. "database=$db;"
. "host=$dbhost;"
. "mysql_ssl=$dbssl;"
. "mysql_skip_secure_auth=1;";
Run Code Online (Sandbox Code Playgroud)
我最近尝试升级我们的 DBD::mysql 版本,但一直遇到DBI connect('database=mydb;host=myhost','myuser',...) failed: Connection using old (pre-4.1.1)错误。
经过数小时的调试,并确定我们的整个系统无法正确选择不更新我们的 mysql 表的密码散列方法的正确选项,我发现使用DBD::Mysql 4.027您可以声明“mysql_skip_secure_auth”作为您的一部分域名
但是,这似乎不起作用。
如果我运行mysql -h $myhost -u $myuser -p --skip-secure-auth,我可以毫无意外地连接,但是尝试使用 DBI/DBD::mysql 执行此操作时,我总是遇到上述错误,就好像该指令被忽略一样。
我也尝试使用mysql_read_default_file相同的选项集,以及简单地mysql_skip_secure_auth在 DSN 中使用。这些东西的任何组合都没有奏效。
我错过了什么吗?
编辑:
跟踪输出(已编辑以删除敏感信息):
imp_dbh->mysql_dr_connect: host = |{host}|, port = 0, uid = {user}, pwd = {pwd}
imp_dbh->mysql_dr_connect: Skipping secure auth
imp_dbh->bind_type_guessing: …Run Code Online (Sandbox Code Playgroud) 我有一个将参数绑定到 LIKE 语句的查询,如下所示:
my $sth = $dbh->prepare('SELECT foo FROM bar WHERE baz LIKE ?');
$sth->execute("%$like%");
Run Code Online (Sandbox Code Playgroud)
但是,$like它是由用户输入的值。因此,如果值包含子句LIKE( &, _, \) 识别的任何特殊字符,这些字符将以未转义的方式传递到数据库并解析为通配符或转义字符。例如,如果用户输入%value,将提交的查询是:SELECT foo FROM bar WHERE baz LIKE '%%value',而不是LIKE '%\%value我所期望的。
目前我正在使用正则表达式手动转义该字段:
# Escape LIKE wildcard characters
$like =~ s!\\!\\\\!g;
$like =~ s!%!\\%!g;
$like =~ s!_!\\_!g;
my $sth = $dbh->prepare('SELECT foo FROM bar WHERE baz LIKE ?');
$sth->execute("%$like%");
Run Code Online (Sandbox Code Playgroud)
但感觉转义是 DBI 应该能够处理的。我尝试过使用DBI::quote,但这是为引用整个字段而设计的,因此在这种情况下它还会引用%我添加的符号,并且文档中DBI::quote特别指出:
quote() 方法不应与“占位符和绑定值”一起使用。
是否有更好的方法将用户提供的输入绑定到 …
我有一个INSERT INTO... SELECT ... FROMSQL 语句,从命令行 shell 执行时运行速度可以接受SQLite's。
但是,如果我使用 Perl 执行相同的语句(复制/粘贴)DBI::SQLite,则该语句会变慢。
原因一定是执行计划:当我让语句从 shell 和内部解释时DBI::SQLite,它们是不同的:快速版本使用最佳索引和表顺序,慢速版本选择以小于最佳方式。
所以,我有两个问题。
我目前在使用DBI收集路由器接口数据的模块的 perl 脚本中有一个插入语句。它每次都有效,但显然存在唯一约束错误,因为重新运行脚本时存在某些项目。我正在尝试进行合并,但我不确定如何通过不从另一个表中选择数据(如我所见的示例)来进行合并。为了更好地理解,perl 脚本通过运行ssh到设备来收集数据,并将某些信息存储到变量中。例如接口名称将是$interface. 等等。
当前插入语句
$dbh->do("INSERT INTO table VALUES (?, ?, ?, ?, ?)", undef, $interface, $id, $device, $description, $user);
Run Code Online (Sandbox Code Playgroud)
我开始编写合并功能,但我似乎无法理解这是如何工作的,因为所有合并语句都从其他表和匹配数据中进行选择,然后进行更新/插入?下面的示例从 2 个不同的表中选择数据并进行匹配,但是我只查看一个表并希望合并新数据。
MERGE INTO bonuses D
USING (SELECT employee_id, salary, department_id FROM employees
WHERE department_id = 80) S
ON (D.employee_id = S.employee_id)
WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01
DELETE WHERE (S.salary > 8000)
WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)
VALUES (S.employee_id, S.salary*.01)
WHERE (S.salary <= 8000);
Run Code Online (Sandbox Code Playgroud)
因此,它正在将数据合并到 …
我有这个代码来获取值计数。
简短的方法:
my $count = $dbh->selectrow_array("SELECT COUNT(name) AS RESCOUNT FROM users");
Run Code Online (Sandbox Code Playgroud)
很长的路要走
my $sth = $dbh->prepare("SELECT COUNT(name) AS RESCOUNT FROM users");
$sth->execute() or die "$DBI::errstr";
my $count = $sth->fetchrow_array();
$sth->finish;
Run Code Online (Sandbox Code Playgroud)
selectrow_array, fetchrow_array --> 但我不需要数组。我检查了文档,但没有发现标量。只是数组和散列的方法。我使用的方法足够快,但我很好奇是否有更好、最快的方法从调用中获取单个值。或者这是最快的方法?
```
{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
library(odbc)
library(DBI)
library(dbplyr)
```
```{sql, connection=con, output.var="df"}
SELECT DB_Fruit.Pear, Store.Name, Cal.Year, Sales.Qty FROM DB_Fruit
```
#> Error: unexpected symbol in "SELECT DB_Fruit.Pear"
Run Code Online (Sandbox Code Playgroud)
我正在尝试在 R Markdown 块中运行 SQL 代码,如上所示。我收到上面显示的“意外符号”错误。\_我最好的猜测是我需要用诸如或 之类的东西来转义下划线,\\_但这些都不会让我的错误消失。
如果我使用 DBI 进行查询(如下所示),则不会收到任何错误:
df <- dbGetQuery(con,'
SELECT DB_Fruit.Pear, Store.Name, Cal.Year, Sales.Qty
FROM DB_Fruit
')
Run Code Online (Sandbox Code Playgroud)
也许该dbGetQuery函数能够_正确解释下划线等内容,而常规 R Markdown 解析器却不能?或者也许有空格被复制/粘贴为一些奇怪的 unicode 字符,这些字符再次被dbGetQuery函数能够解释,而常规 R Markdown 解析器却不能?
可能的罪魁祸首是什么?我该怎么办?
下面是我在 R 中用于从 PostgreSQL 数据库中提取 ID 的代码片段。当我运行该函数时,我从 R 收到以下警告消息:
在 result_create(conn@ptr, statements) 中:关闭打开的结果集,取消之前的查询
options(warn=-1)如何避免出现此警告消息而不在代码开头 使用,抑制警告而不是
con <- dbConnect(RPostgres::Postgres(),
user = "postgres",
dbname = "DataBaseName",
password = "123456",
port = 5431)
get_id <- function(connection, table){
query <- toString(paste("SELECT id FROM ", table, sep = ""))
data_extract_query <- dbSendQuery(connection, query)
data_extract <- dbFetch(data_extract_query)
return(data_extract)
}
get_id(con, "users")
Run Code Online (Sandbox Code Playgroud) 我正在尝试通过 R studio 使用 DBI:: dbAppendTable() 将数据帧插入到雪花数据库的表中。datafarme 中的行数为 5000。仅当我总共加载所有 5000 行时,才会出现上述错误。在表中插入 1024 行后查询失败。如果我使用循环加载大小为 100 的批次,它不会失败。我的字符串大小也不会超出 VARCHAR 列大小。我从未见过雪花出现此错误。希望有人对此有任何见解。
dbi ×10
perl ×7
sql ×4
r ×3
oracle ×2
dbplyr ×1
etl ×1
mysql ×1
oracle11g ×1
perl-module ×1
postgresql ×1
r-markdown ×1
rpostgresql ×1
snowflake-cloud-data-platform ×1
sqlite ×1