I'm working on upgrading a Codeigniter app I have running on 1.7.2 to 2.0.3 but I'm not able to connect to SQL Server . Both versions are running on the same server running php 5.2.10 and connecting to the same SQL Server.
This is the error from CI 2.0.3
Unable to connect to your database server using the provided settings.
Filename: core/Loader.php
Line Number: 260
This is the connection string I'm using which of course works on 1.7.2
$db['reports']['hostname'] = "mysqlserver";
$db['reports']['username'] = "sqluser";
$db['reports']['password'] = "sqlpass";
$db['reports']['database'] = "SQLReportDB";
$db['reports']['dbdriver'] = "mssql";
$db['reports']['dbprefix'] = "";
$db['reports']['pconnect'] = TRUE;
$db['reports']['db_debug'] = TRUE;
$db['reports']['cache_on'] = FALSE;
$db['reports']['cachedir'] = "";
$db['reports']['port'] = 972;
In the controller I call the connection with this
$report_db = $this->load->database('reports', TRUE);
Below is the function in the loader file where it reports the failure.
Line 260 is return DB($params, $active_record);
/**
* Database Loader
*
* #param string the DB credentials
* #param bool whether to return the DB object
* #param bool whether to enable active record (this allows us to override the config setting)
* #return object
*/
public function database($params = '', $return = FALSE, $active_record = NULL)
{
// Grab the super object
$CI =& get_instance();
// Do we even need to load the database class?
if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db))
{
return FALSE;
}
require_once(BASEPATH.'database/DB.php');
if ($return === TRUE)
{
return DB($params, $active_record);
}
// Initialize the db variable. Needed to prevent
// reference errors with some configurations
$CI->db = '';
// Load the DB class
$CI->db =& DB($params, $active_record);
}
Here are some settings I use in connecting to a SQL Server you haven't listed. Might be required due to upgrade...
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
$db['reports']['port'] is no longer valid
The port needs to be added to the end of the server
$db['reports']['hostname'] = "mysqlserver:972";
Related
I have a Codeigniter website that is hosted on a global server and connected to the global database.
I want to connect another database that is hosted locally(192.168.x.x).
Is there any way to achieve this?
In real-world CodeIgniter projects, developers need to work with multiple databases at the same time. This presents a unique challenge to developers. Since this is a common enough problem, CodeIgniter offers a simple solution for it.
In order to use multiple database connections in your CodeIgniter project, you just need to create multiple configuration arrays that simplify working with multiple databases.
The Default Configuration Array
Following is the structure of the default Codeigniter database configuration array:
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'root';
$db['default']['password'] = '';
$db['default']['database'] = 'mydefaultdatabase';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = FALSE;
$db['default']['cache_on'] = FALSE;
$db['default']['autoinit'] = FALSE;
$db['default']['stricton'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
So in order to create another database connection, you should create another configuration array. This array has to follow the same structure. Here is an example of the array:
$db['anotherdb']['hostname'] = 'XXX.XXX.X.XXX';
$db['anotherdb']['username'] = 'another_user';
$db['anotherdb']['password'] = '';
$db['anotherdb']['database'] = 'anotherdatabase';
$db['anotherdb']['dbdriver'] = 'mysql';
$db['anotherdb']['dbprefix'] = '';
$db['anotherdb']['pconnect'] = TRUE;
$db['anotherdb']['db_debug'] = FALSE;
$db['anotherdb']['cache_on'] = FALSE;
$db['anotherdb']['cachedir'] = '';
$db['anotherdb']['char_set'] = 'utf8';
$db['anotherdb']['dbcollat'] = 'utf8_general_ci';
$db['anotherdb']['swap_pre'] = '';
$db['anotherdb']['autoinit'] = FALSE;
$db['anotherdb']['stricton'] = FALSE;
Connect to the Right Database
At this point, you have two databases in your sample project. To connect to a specific database, you must specify the database name. Here is the proper syntax:
this->load->database(anotherdb, TRUE)
After connecting to the database, you can perform databse operations as shown below:
load 'anotherdatabase'
$this->legacy_db = $this->load->database(anotherdatabase, true);
Fetch result from 'mydefaultdatabase'
$this->legacy_db->select ('*');
$this->legacy_db->from ('mydefaultdatabase');
$query = $this->legacy_db->get();
$result = $query->result ();
Now if you need to work with the second database, you have to send the connection to a variable that is usable in your model function:
function db_calling_model_method()
{
$otherdb = $this->load->database('anotherdb', TRUE); // the TRUE paramater tells CI that you'd like to return the database object.
$query = $otherdb->select('column_one, column_two')->get('table');
var_dump($query);
}
Close the Connections
CodeIgniter does close the database connections after it determines that the code no longer need the connection. However, as a good practice, developers should close the connections explicitly. Here is how to take care of the issue:
$this->db->close(); // for default Connection
$this->legacy_db->close(); //
When using scripting option Permissions in SQL Server 2008 and above, the database creation script does not get scripted. Instead, an ALTER DATABASE statement is scripted.
I am using SQL Server 2008 and higher. Using C# SMO .Net assemblies v12.0.2000.8.
These are my script options:
ScriptingOptions so = new ScriptingOptions();
so.DriAll = true;
so.EnforceScriptingOptions = false;
so.IncludeDatabaseContext = true;
so.AllowSystemObjects = false;
so.IncludeHeaders = true;
so.IncludeIfNotExists = true;
so.Indexes = true;
so.NoCommandTerminator = false;
so.NoFileGroup = true;
// TODO: script user permissions
so.Permissions = true;
so.PrimaryObject = true;
so.SchemaQualify = true;
so.ScriptOwner = true;
so.ScriptSchema = true;
so.ScriptDrops = false;
so.Triggers = true;
//so.ExtendedProperties = true;
so.WithDependencies = false;
so.ScriptBatchTerminator = true;
so.TargetServerVersion = SqlServerVersion.Version105;
so.ContinueScriptingOnError = true;
I do not use a Transfer Object.
When I set Permissions to false, the CREATE DATABASE statement is generated. When I set Permissions to true, an ALTER DATABASE statement is scripted instead.
I want to be able to script the user permissions AND have the CREATE DATABASE statement included in the script instead of the ALTER DATABASE statement.
A restore performed with C# code using SMO objects restores fine when original database is in SIMPLE recovery mode. We got problems with one database where the restore missed all content from a certain table, where all data was inserted late in process. The database showed to be in BULK LOGGED recovery mode. After changing to SIMPLE and doing a new backup, it restored fine, using our code.
We have tried different settings on the restore object, but found none that fixes the problem. We are under the impression that the restoring ignores data in the log.
The basic restore looks like this:
sqlServer = new Server(new ServerConnection(instanceName));
restore = GetRestore();
restore.PercentComplete += PercentCompleteAction;
restore.Complete += CompleteAction;
restore.SqlRestore(sqlServer);
the GetRestore function is basically implemented like this:
restore = new Restore();
var deviceItem = new BackupDeviceItem(backupFileName, DeviceType.File);
restore.Devices.Add(deviceItem);
restore.Database = newDatabaseName;
restore.NoRecovery = false;
restore.Action = RestoreActionType.Database;
restore.ReplaceDatabase = false;
return restore;
There are no error messages - just missing content in one table.
Added try:
I took a guess at the solution below, but it didn't help:
restore.ReplaceDatabase = false;
restore.NoRecovery = true;
restore.Action = RestoreActionType.Database;
restore.SqlRestore(sqlServer);
restore.ReplaceDatabase = true;
restore.NoRecovery = true;
restore.Action = RestoreActionType.Log;
restore.SqlRestore(sqlServer);
restore.ReplaceDatabase = true;
restore.NoRecovery = false;
restore.Action = RestoreActionType.Files;
restore.SqlRestore(sqlServer);
You need select a correct FileNumber in your Log file, see this method can solve your problem:
public static void restaurarBackup(string pathFileBak)
{
SqlConnection conn = new SqlConnection(Connection.getCon());
Server smoServer = new Server(new ServerConnection(conn));
string localFilePath = pathFileBak;
string db_name = "ETrade";
string defaultFolderEtrade = #"C:\ETrade\";
Restore rs = new Restore();
rs.NoRecovery = false;
rs.ReplaceDatabase = true;
BackupDeviceItem bdi = default(BackupDeviceItem);
bdi = new BackupDeviceItem(localFilePath, DeviceType.File);
rs.Devices.Add(bdi);
DataTable dt = rs.ReadFileList(smoServer);
foreach (DataRow r in dt.Rows)
{
string logicalFilename = r.ItemArray[dt.Columns["LogicalName"].Ordinal].ToString();
string physicalFilename = defaultFolderEtrade + Path.GetFileName(r.ItemArray[dt.Columns["PhysicalName"].Ordinal].ToString());
rs.RelocateFiles.Add(new RelocateFile(logicalFilename, physicalFilename));
}
DataTable backupHeaders = rs.ReadBackupHeader(smoServer);
rs.FileNumber = Convert.ToInt32(backupHeaders.AsEnumerable().Max(backupInfo => backupInfo["Position"]));
rs.Database = db_name;
smoServer.KillAllProcesses(rs.Database);
Microsoft.SqlServer.Management.Smo.Database db = smoServer.Databases[rs.Database];
db.DatabaseOptions.UserAccess = DatabaseUserAccess.Single;
rs.SqlRestore(smoServer);
db = smoServer.Databases[rs.Database];
db.SetOnline();
smoServer.Refresh();
db.Refresh();
}
If you want look backups in your Log file, see this query:
SELECT database_name, name, backup_start_date,
backup_finish_date, datediff(mi, backup_start_date, backup_finish_date) [tempo (min)],
position, first_lsn, last_lsn, server_name, recovery_model,
type, cast(backup_size/1024/1024 as numeric(15,2)) [Tamanho (MB)], B.is_copy_only
FROM msdb.dbo.backupset B
I am trying to find newly created tables in the target database on publishing. Using DAC Fx I am able to find the differences and delete the tables after moving the newly created table to another db.
I developed and tested the code with IntegratedSecurity. Started failing on machines with SQLServer logins.
The moment I toggle the IntegratedSecurity to true it works. Is it a bug?
private void Analyse()
{
try
{
var sourceDacpac = new SchemaCompareDacpacEndpoint(DacPacSrc);
var csb = new SqlConnectionStringBuilder(ConnectionString);
csb.IntegratedSecurity = false;
var targetDatabase =new SchemaCompareDatabaseEndpoint(csb.ToString());
var comparison = new SchemaComparison(sourceDacpac, targetDatabase);
comparison.Options.DropObjectsNotInSource = true;
var result = comparison.Compare();
if (result.GetErrors().Any())
{
throw new Exception("Compare failed " + result.GetErrors().FirstOrDefault().Message);
}
var delta = new List<string>();
if (result.Differences != null && result.Differences.Any())
{
var deltaTables = result.Differences.Where(x => x.Name == "Table" && x.UpdateAction == SchemaUpdateAction.Delete);
delta = deltaTables.Select(x => x.TargetObject.Name.ToString()).ToList();
}
FindingDeltaCompleted?.Invoke(this, new DeltaEventArgs(delta));
}
catch (Exception ex)
{
Logging.HandleException(ex);
}
}
Try setting Persist Security Info=True in the SQL Authentication connection string.
SSDT/DAC Fx saves connection strings in registry under HKEY_CURRENT_USER\SOFTWARE\Microsoft\SSDT\ConnectionStrings. When Persist Security Info=True is not set, it won't restore the password when loading the connection strings from registry.
I created an integration service project with three connection managers (which are defined in project level), now I have an SSIS package (.dtsx file) and I want to use it in my app.
So I use Microsoft.SqlServer.Dts namespace as below:
string pkgLocation;
Package pkg;
Microsoft.SqlServer.Dts.Runtime.Application app;
DTSExecResult pkgResults;
pkgLocation = #"D:\My Job\Tadbirgaran\Integration Services Project\MyPackage.dtsx";
app = new Microsoft.SqlServer.Dts.Runtime.Application();
pkg = app.LoadPackage(pkgLocation, null);
pkgResults = pkg.Execute();
but this code does not load project connection managers obviously, so is there any way that I can load connection manager files programmatically and add them to the package connection property? or should I define connections in my package in the integration service project?
You can use configurations to control the connection properties programmatically. Here is an example.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Tasks.BulkInsertTask;
namespace configuration_API
{
class Program
{
static void Main(string[] args)
{
// Create a package and set two properties.
Package pkg = new Package();
pkg.EnableConfigurations = true;
pkg.ExportConfigurationFile(#"C:\conf.xml");
// Create a variable object and add it to the
// package Variables collection.
Variable varPkg = pkg.Variables.Add("var", false, "", 100);
varPkg.Value = 1;
string packagePathToVariable = varPkg.GetPackagePath();
// Create a configuration object and add it to the
// package configuration collection.
Configuration config = pkg.Configurations.Add();
// Set properties on the configuration object.
config.ConfigurationString = "conf.xml";
config.Description = "My configuration description";
config.ConfigurationType = DTSConfigurationType.ConfigFile;
config.PackagePath = packagePathToVariable;
// Save the package and its configuration.
Application app = new Application();
app.SaveToXml(#"c:\pkg.xml", pkg, null);
// Reload the package.
Package p1 = app.LoadPackage(#"c:\pkg.xml", null);
// Review the configuration information.
Configurations configs_After = pkg.Configurations;
foreach(Configuration confAfter in configs_After)
{
Console.WriteLine("ConfigurationString is {0}", confAfter.ConfigurationString);
Console.WriteLine("ConfigurationType is {0}", confAfter.ConfigurationType);
Console.WriteLine("CreationName is {0}", confAfter.CreationName);
Console.WriteLine("Description is {0}", confAfter.Description);
Console.WriteLine("Assigned ID is {0}", confAfter.ID);
Console.WriteLine("Name is {0}", confAfter.Name);
}
}
}
}
I ended up loading the project instead of package and setting connections from project to package as below:
private void SSISLoadData()
{
Project ssisProject = null;
DTSExecResult pkgResults;
try
{
ssisProject = Project.OpenProject(#"D:\My Job\TDB\Integration Services Project\bin\Development\Integration Services Project.ispac");
Package pkg = ssisProject.PackageItems[0].LoadPackage(null);
for (int i = 0; i < ssisProject.ConnectionManagerItems.Count; i++)
pkg.Connections.Join(ssisProject.ConnectionManagerItems[i].ConnectionManager);
pkg.Connections[0].ConnectionString = dataFolderPath + "\\*.csv";
pkg.Connections[1].ConnectionString = string.Format("Data Source =.; Initial Catalog = TDB; Provider = SQLNCLI11.1; Integrated Security = SSPI; Initial File Name = {0};", dbPath);
pkg.Connections[2].ConnectionString = string.Format("Data Source =.; Initial Catalog = TDBRawData; Provider = SQLNCLI11.1; Integrated Security = SSPI; Initial File Name = {0}\\TDBRawData.mdf;", Environment.CurrentDirectory);
pkgResults = pkg.Execute();
MessageBox.Show(pkgResults.ToString());
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
finally
{
if (ssisProject != null)
ssisProject.Dispose();
}
}
I don't know if there is a better solution for this problem, but it works.