Yii2: Connect to Oracle database - database

I need to connect a Yii2 model to an Oracle database but it is not working despite reading several answers on this topic.
The Oracle login credentials that I use to manually log in are similar to:
host: hosturl.abc.com
port: 1521
SID: sidname
user: username
password: passABC
In the manual login process, I then need to select the appropriate Schema, after which I can see all tables.
I am not clear how to include these details in the oci connection. Here is what I have done without success:
'db2' => [
'class' => 'yii\db\Connection',
'dsn' => 'oci:dbname=//hosturl.abc.com:1521/sidname;charset=UFT-8',
'username' => 'username',
'password' => 'passABC'
],
I get an error "The table does not exist: TableName" however, I get this message even if I supply completely random details ie wrong username, wrong host, wrong password etc)
I am not clear why I cannot connect. Perhaps the Oracle database is rejecting all queries? Do I need to include the SID in the connection credentials?
Any help appreciated
UPDATE
I think there must be a more general problem with my installation. I am trying a raw connection as follows:
$conn = oci_connect("username", "passABC", "//hosturl.abc.com/sidname");
if (!$conn) {
print "There is a problem";
} else {
print "Connected to Oracle!";
}
This returns the following error:
Call to undefined function oci_connect()
Any suggestions? This looks like a problem with my php setup??

SOLVED!
1) oci_connect not working: SOLVED
Please see this post for more details How do I connect PHP 7.x to Oracle database on RedHat / CentOS?. This fix was required for Yii2 to connect to Oracle.
2) Yii2 db credentials for an Oracle database
/common/config/main-local:
'db' = [
'class' => 'yii\db\Connection',
'dsn' => 'oci:dbname=//hosturl:1521/SID;charset=UTF8',
'username' => 'dbusername',
'password' => 'dbpassword',
]
I tried a number of Yii2 oci8 extensions but none of them worked for me. Instead, the fix (1) for the oci_connect worked and no additional Yii2 drivers were required. I was able to use the standard 'yii\db\Connection' class.
3) Database Schema
Within the Oracle database we have a number of schemas and I wasn't sure how to query a specific table within a particular schema. Ultimately the solution was simple: Within each model, prepend the schema name to the table name. For example:
class myTable extends ActiveRecord
{
public static function tableName()
{
return 'schemaName.myTable';
}

Related

How to whitelist ip address to access oracle database

I am new to oracle database. I work on 12c version oracle database which is hosted in linux platform. I have to whitelist a list of ip addresses to access the oracle database.
Example: Below are the server details and i need to add my ipaddress to connect to the database
(PROTOCOL = TCP)(HOST = 192.168.56.122) (PORT = 1521)
kishan 192.108.10.132 xyz#gmail.com
I have gone through these documents but it was not quite helpful. Any help would be much appreciated!
https://docs.oracle.com/en/cloud/paas/casb-cloud/palug/putting-ip-addresses-blacklists-or-whitelists.html#GUID-17060E3D-D8B6-41F1-AAEB-9CC3F4D7B670
https://docs.oracle.com/en/cloud/paas/exadata-express-cloud/csdbp/configure-ip-whitelist-policy.html
Looks like you're looking for ACL (Access Control List). Here's an example:
Create ACL:
BEGIN
DBMS_NETWORK_ACL_ADMIN.create_acl (
acl => 'kishan.xml',
description => 'HTTP Access',
principal => 'KISHAN', -- user in your database
is_grant => TRUE,
privilege => 'connect',
start_date => NULL,
end_date => NULL);
END;
/
Assign ACL:
BEGIN
DBMS_NETWORK_ACL_ADMIN.assign_acl (acl => 'kishan.xml',
HOST => '192.108.10.132',
lower_port => NULL,
upper_port => NULL);
END;
/
Add privilege
BEGIN
-- TRAFOGLED
DBMS_NETWORK_ACL_ADMIN.add_privilege (acl => 'kishan.xml',
principal => 'KISHAN',
is_grant => TRUE,
privilege => 'connect',
start_date => NULL,
end_date => NULL);
DBMS_NETWORK_ACL_ADMIN.add_privilege (acl => 'kishan.xml',
principal => 'KISHAN',
is_grant => TRUE,
privilege => 'resolve',
start_date => NULL,
end_date => NULL);
END;
/
COMMIT;
After you've done all that, user KISHAN should have access to 192.108.10.132. If there are other users that should gain the same access, just add them into the "add privilege" script.
ACLs as described by #Littlefoot control access from within the database to external resources (e.g. a PL/SQL stored procedure accessing a web service or e-mail server). If you're talking about whitelisting database clients, connecting to the DB from other hosts, there are a couple of options, but be careful not to work yourself into a corner in terms of administrative overhead. It is very important to consider what is the actual problem you are trying to solve.
You can use
the host server's local firewall (e.g. iptables, firewall1, etc.) to restrict access to port 1521 (or whatever port you're using);
the TCP.INVITED_NODES parameter in sqlnet.ora (see here: https://docs.oracle.com/en/database/oracle/oracle-database/19/netrf/parameters-for-the-sqlnet.ora.html#GUID-897ABB80-64FE-4F13-9F8C-99361BB4465C);
or use Oracle Connection Manager if you have an Enterprise Edition database.
In general I wouldn't restrict to anything more narrow than a subnet, though. The reason for that is that there isn't any good way to do it more precisely: IP addresses tend to change frequently with DHCP, which could result in a user being unintentionally locked out, and they can be easily spoofed by bad actors. Tracking each individual IP is an administrative nightmare, too.
See these articles I wrote up last year for more detail and some of the important questions to consider:
https://pmdba.wordpress.com/2020/02/18/how-to-limit-a-user-connection-to-a-specific-ip-address/
https://pmdba.files.wordpress.com/2013/03/deploying-an-oracle-11gr2-connection-manager.pdf

Column "" declared twice in table "status" in Propel 2

I'm trying to reverse generate a schema from a MSSQL database using Propel 2. I've set up my YAML configuration file as usual:
dbname:
adapter: mssql
classname: Propel\Runtime\Connection\ConnectionWrapper
dsn: "dblib:host=123.456.789.012;dbname=dbname"
user: username
password: password
attributes:
When I run the command propel reverse 'dbname' I receive the error:
[Propel\Generator\Exception\EngineException]
Column "" declared twice in table "Status"
Which is obviously thrown here:
https://github.com/propelorm/Propel2/blob/master/src/Propel/Generator/Model/Table.php#L499
#r499
Why does Propel attempt to add 'empty' columns? My SQL server management studio does not display empty columns at all when I look at the design of the DB table Status, it only displays the two columns it contains (uid and name).
Edit:
So I went digging into the code of Propel, and it seems to go wrong here:
https://github.com/propelorm/Propel2/blob/62859fd0ed3520b7d7afbbdeac113edaf160982b/src/Propel/Generator/Reverse/MssqlSchemaParser.php#L124
protected function addColumns(Table $table)
{
$dataFetcher = $this->dbh->query("sp_columns '" . $table->getName() . "'");
foreach ($dataFetcher as $row) {
$name = $this->cleanDelimitedIdentifiers($row['COLUMN_NAME']);
$table->getName() correctly returns the right table name. When I print dataFetcher it's a PDO object. However:
$row gives the following array:
Array(
[0] => My DBname
[1] => My DBprefix
[2] => Status
[3] => uid
[4] => 4
[5] => int identity
etc. no string indices hence COLUMN_NAME is empty.
(Posted on behalf of the OP):
This is a bug in the Propel MSSQL schema parser: https://github.com/propelorm/Propel2/issues/863.

Django SQL Server Error: "Cannot create new connection because in manual or distributed transaction mode."

I have some strange issue with querying SQL Server from django.
When I query db twice in single request, I got errors in some cases. Namely when first db query returns big amount of data, we end up with error while querying db second time.
Details:
We're using Microsoft SQL Server backend for Django (https://bitbucket.org/Manfre/django-mssql/src) running on windows.
We want allow user to filter data from some table ("Activity") via form, display it on the website's table and then show related data from another table ("Frames") on map.
class Frames(models.Model):
...
class Activity(models.Model):
frame_from = models.ForeignKey(Frames, ...)
...
The problem is: when we want to filter larger amount of data from Activity (let's say 200rows x 6 colums), we can not make other queries in the same request on table Frames (MARS is turned on in Django settings.py):
result = Aktywnosci.objects.filter(qset1)
is always ok, but
path = Frames.objects.filter(qset2)
when the previous query returned larger amount of data, raises OLE DB Error:
'Microsoft OLE DB Provider for SQL Server' Error: Cannot
create new connection because in manual or distributed transaction mode.
PS. Database settings from settings.py:
# Database for this installation.
DATABASES = {
'default':{
'ENGINE': 'django.db.backends.sqlserver_ado',
'NAME': '***',
'USER': '***',
'PASSWORD': '***',
'HOST': '***',
'PORT': '',
'OPTIONS' : {
'provider': 'SQLOLEDB',
'use_mars': True,
}
}
}
PS2. I came across this issue on the google-code page of djang-mssql: http://code.google.com/p/django-mssql/issues/detail?id=79 - but it seems to be solved in new version of package...
What can I do about it?
Thanks in advance
We got the solution at bitbucket: https://bitbucket.org/Manfre/django-mssql/issue/13/ole-db-provider-for-sql-server-error from Michael Manfre - thanks a lot for this.
The solution is following:
"SQLOLEDB and MARS doesn't work very well and I intend on changing all of the documentation and defaults to assume a native client driver will be used. Try using the native client; "SQLNCLI10" or "SQLNCLI11".
DATABASES = {
'default': {
'ENGINE': 'sqlserver_ado',
'NAME': 'mydb',
'HOST': r'localhost',
'USER': '',
'PASSWORD': '',
'OPTIONS': {
'provider': 'SQLNCLI10',
'extra_params': 'DataTypeCompatibility=80;MARS Connection=True;',
},
}
}
Is "use_mars=True" set up in your "settings.py" file?
http://django-mssql.readthedocs.org/en/latest/settings.html
If this doesn't work, I have a question: is your selection in SQL Server involving tables with triggers on them (transact SQL scripts) - in this case the SQL Server will use a static cursor instead of a firehose one (which is what you need) therefore you will get your error. Try to get rid of the triggers, use some views in SQL Server and select from them instead of tables.

CodeIgniter dbutil & db point to different database (How to backup current database)

I have a trouble with dbutil and db.
Below is my code (a constructor of my model):
public function __construct(){
// I save my database configuration in CI session
$this->load->library('session');
$config = $this->session->userdata("db_config");
if($config){ // $config is now equal contains of my database configuration
$this->db = $this->load->database($config, TRUE);
}else{
$this->db = $this->load->database();
}
$this->load->dbutil();
echo '<pre>'.print_r($this->db, TRUE).'</pre>';
echo '<pre>'.print_r($this->dbutil, TRUE).'</pre>';
}
I found that $this->db and $this->dbutil point to different databases.
$this->db point to database config from session:
....
[username] => root
[password] => toor
[hostname] => localhost
[database] => coba
....
While $this->dbutil point to database config from my configuration file (application/config/database.php):
....
[username] => root
[password] => toor
[hostname] => localhost
[database] => module_devel
....
This is not expected, since I expect both of $this->db and $this->dbutil point to the same database
I've also check PHP: CodeIgniter; Managing two db connections; variable database parameters. But, for me the solution doesn't work at all.
So, anyone can discover what's wrong here?
It seems that it is a bug of CodeIgniter. But, dbutil is not the only we can use.
There are many alternatives to emulate what dbutil can do.
In my case, I want to generate a "create table" script. I end up using
$query = $this->db->query("SHOW CREATE TABLE `$table_name`");
And to generate SQL insert script, I do manual select, loop through the records and produce the script.
Hope this can help anyone else with similar problem

how to connect SQL Server with perl

I know there is a similar question: Connect to SQL Server 2005 from Perl and do a SELECT , but I tried the accepted answer and am unable to get it to work.
Assuming I have a db named test, and would love to do a select from mytable
(select id, name from mytable)
Code is from the link above with updated dsn:
use strict;
use warnings;
use DBI;
# Insert your DSN's name here.
my $dsn = 'database=test'
# Change username and password to something more meaningful
my $dbh = DBI->connect("DBI::ODBC::$dsn", 'username', 'password')
# Prepare your sql statement (perldoc DBI for much more info).
my $sth = $dbh->prepare('select id, name from mytable');
# Execute the statement.
if ($sth->execute)
{
# This will keep returning until you run out of rows.
while (my $row = $sth->fetchrow_hashref)
{
print "ID = $row->{id}, Name = $row->{name}\n";
}
}
# Done. Close the connection.
$dbh->disconnect;
This is what I got when running the script:
Can't connect to data source 'ODBC::database=test' because I can't work out what
driver to use (it doesn't seem to contain a 'dbi:driver:' prefix and the DBI_DR
IVER env var is not set) at script.pl line 9
Looks like the problem is in the dsn but I have no idea how to fix it (I am on sql 2005, active perl 5.10 and windows xp).
Edit:
I used the following code to verified whether ODBC is installed.
use DBI;
print join (", ", DBI->installed_versions);
Output:
It looks like ODBC is indeed in the list.
ADO, CSV, DBM, ExampleP, File, Gofer, ODBC, SQLite, Sponge, mysql
What am I missing?
I got the same error with SQLite just now, and it looks like you did the same thing wrong as me. Note the number of colons in the first argument - this is the wrong format:
my $db = DBI->connect('DBI::SQLite::dbname=testing.db', '', '', {RaiseError => 1, AutoCommit => 1});
There should actually only be two colons, not two pairs of colons in the first argument:
my $db = DBI->connect('DBI:SQLite:dbname=testing.db', '', '', {RaiseError => 1, AutoCommit => 1});
Question answered despite its age because it's still top of the results in Google for this particular error message
Try setting your DSN to something like:
my $dbh = DBI->connect("dbi:ODBC:test", 'username', 'password')
If that doesn't work, ensure you have DBD::ODBC installed by running:
perl -MDBI -e 'DBI->installed_versions;'
Assume SQL server is located on local server, connection below can be right:
my $DSN = "driver={SQL Server};Server=127.0.0.1;Database=test;UID=sa;PWD=123456";
my $dbh = DBI->connect("dbi:ODBC:$DSN");

Resources