Oracle client software version 8.1.7 or greater. Hatası hakkında

Oracle yine iş başında. Oracle ile ilgilenenler birazcık bana kızabilir ama oldum olası sevemedim şunu 😀 Bir müşterimiz ile entegrasyon yaparken eski bir yazılımımız bağlantı hatası alıyordu. Hata “System.Data.OracleClient requires Oracle client software version 8.1.7 or greater.”  Türkçe Meali “System.Data.OracleClient, Oracle istemci version 8.1.7 veya daha sonraki sürümünü gerektirir.”

Daha öncesinde ORACLE tarafında aldığımız bir hatanın çözümü için bir yazı paylaşmıştım. C# ile geliştirilmiş olan bir yazılım üzerinde aldığımız hata idi. Yazıya buradan ulaşabilirsiniz..

Hatanın Türkçe karşılığı anlaşıldığı gibi Oracle Client nesnesinin versiyonun düşük ve eski olmasından kaynaklanıyordu. Bunun için aşağıdaki linkten ODAC’lardan yeni versiyonundan birisinin indirilip kurulum sonrası çözüldüğünü gördüm.

İndirmek biraz zahmetli. Çünkü hesap bilgileri vs. istiyor. Aynı zamanda Oracle sitesi bazen hata veriyor. Dikkat edin. Çıldırmanıza ve çılgın atmanıza sebebiyet verebilir. 🙂

https://www.oracle.com/database/technologies/dotnet-odacdev-downloads.html

Yukarıdaki linkten indirip istenirse sadece Oracle Client nesnesinin kurulması yeterli.

Okumaya devam et “Oracle client software version 8.1.7 or greater. Hatası hakkında”

C# Oracle Veritabanı Bağlantı Hatası ( TNS:listener was not given the SERVICE_NAME in CONNECT_DATA )

Bir entegrasyon projemizde gittik Oracle’a denk geldik. Onda da hata ile karşılaştık. Yanlış anlaşılmasın denk geldik işte 🙂 Oracle tarafı ile pek bir tecrübem olduğu söylenemez. Fakat Google gibi bir kaynak elimizin altındayken çözümü bulmamak ayıp olurdu.

Alınan hata aşağıdaki gibi bir hatadır.

System.Data.OracleClient.OracleException (0x80131938): ORA-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA

konum: System.Data.OracleClient.OracleException.Check(OciErrorHandle errorHandle, Int32 rc)
konum: System.Data.OracleClient.OracleInternalConnection.OpenOnLocalTransaction(String userName, String password, String serverName, Boolean integratedSecurity, Boolean unicode, Boolean omitOracleConnectionName)
konum: System.Data.OracleClient.OracleInternalConnection..ctor(OracleConnectionString connectionOptions)
konum: System.Data.OracleClient.OracleConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
konum: System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
konum: System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
konum: System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
konum: System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
konum: System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
konum: System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
konum: System.Data.OracleClient.OracleConnection.Open()

Yukarıdaki gibi bir hata alıyorduk. Hatanın ana teması ise “TNS:listener was not given the SERVICE_NAME in CONNECT_DATA” artık bu ne demekse ( ORACLE ile uğraşanlar biliyorlardır diye tahmin ediyorum 🙂 )

Çözümümüz ise Program tarafında SQL Connection için yazılan string içerisine HOST kısmında aşağıdaki cümleciği yazmak oldu.

(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=BAGLANTI_YAPILACAK_SERVER)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=opera)))

BAGLANTI_YAPILACAK_SERVER bilgisi bağlanacak olduğunuz server bilgisidir. localhost, Server’ın kendi hostname’i, IP Adresi gibi bilgiler olmaktadır.

 

MSSQL CSV Formatında Saatlik Yedek Aldırma İşlemi

Bir projemizde kullanılan MSSQL Server Database sistemi için saatlik yedeklemelere ihtiyaç duyduk.

C#.Net ortamında çalışmaktadır. Otomatik olarak her saat yedek alabilmesi için ise outputtaki .exe dosyasını “Zamanlanmış Görevlere ( Task Scheduler )” zamanlanmış görev olarak çalıştırıyoruz. Veritabanındaki tabloları listeleyip tüm dataları dump ediyoruz. CSV formatında dosyaya yazıyoruz ve sıkıştırma işlemini gerçekleştiriyoruz. Böylece disk kaybı yaşamıyoruz.

Birden fazla Database mevcut ise önce onları çekip ayrı ayrı da çalıştırabilirsiniz. Geliştirilip farklı varsyonlarda eklenebilir. FTP olarak farklı bir alanada yükleme yapılabilir. Bu sistemde şuanda tüm dosyalar tutuluyor. Manuel olarak silmek yerine birkaç saat öncesine ait klasörleri silebilirsiniz. Diskten kazanmış olursunuz.

Program parçasını full olarak paylaşıyorum;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;
using System.Data;
using System.Text;
using System.IO.Compression;

namespace WindowsFormsApp7
{
static class Program
{
/// 
<summary>
/// The main entry point for the application.
/// </summary>

/// 
private static string directoryPath = @"c:\temp";
[STAThread]

static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

SqlConnection sqlCon = new SqlConnection("Data Source=IP;Initial Catalog=DATABASE;User ID=USERNAME;Password=PASSWORD;MultipleActiveResultSets=True;");
sqlCon.Open();
string sql = "SELECT sc.name + '.' + ta.name TableName ,SUM(pa.rows) RowCnt FROM sys.tables ta INNER JOIN sys.partitions pa ON pa.OBJECT_ID = ta.OBJECT_ID INNER JOIN sys.schemas sc ON ta.schema_id = sc.schema_id WHERE ta.is_ms_shipped = 0 AND pa.index_id IN(1,0) GROUP BY sc.name,ta.name having SUM(pa.rows) > 0 and sc.name +'.'+ ta.name IN ( 'dbo.EFAT_ZARF' ) ORDER BY SUM(pa.rows) DESC";
SqlCommand com = new SqlCommand(sql, sqlCon);
SqlDataReader read = com.ExecuteReader();

//string dirname = "DOSYAYOLU" + (DateTime.Now).ToString("yyyy-MM-dd");
string dirname = "C:/SQL_BACKUP/" + (DateTime.Now).ToString("yyyy-MM-dd");
CreateIfMissing(dirname);

dirname += "/" + (DateTime.Now).ToString("HH");

CreateIfMissing(dirname);
string rar_dir = @"" + dirname;
string rar_path = @"" + dirname + ".zip";
List<string> filess = new List<string>();
while (read.Read())
{
string fileName = dirname + "/" + read.GetValue(0) + ".csv";
filess.Add(fileName);
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.CommandText = "SELECT * FROM " + read.GetValue(0) + " with (NOLOCK)";
sqlCmd.Connection = sqlCon;

sqlCmd.Dispose();
using (var CommandText = new SqlCommand("SELECT * FROM " + read.GetValue(0) + " with (NOLOCK)"))
using (var reader = sqlCmd.ExecuteReader())
//using (var outFile = File.CreateText(fileName))
using (StreamWriter outFile = new StreamWriter(File.Open(fileName, FileMode.Create), Encoding.UTF8))
{
string[] columnNames = GetColumnNames(reader).ToArray();
int numFields = columnNames.Length;
outFile.WriteLine(string.Join(",", columnNames));
if (reader.HasRows)
{
while (reader.Read())
{
string[] columnValues =
Enumerable.Range(0, numFields)
.Select(i => get_string( reader.GetValue(i) ))
.Select(field => string.Concat("\"", field.Replace("\"", "\"\""), "\""))
.ToArray();
outFile.WriteLine(string.Join(",", columnValues));
}
}
}

}
sqlCon.Close();
directoryPath = rar_dir;
DirectoryInfo directorySelected = new DirectoryInfo(directoryPath);
Compress(directorySelected);
foreach (var item in filess)
{
if (File.Exists(item))
File.Delete(item);
}

}

public static string get_string( object ss )
{
if (!(ss.ToString().Length > 2))
return ss.ToString();
if (ss.ToString().Substring(0, 2) == "0x")
return System.Text.Encoding.UTF8.GetString((Byte[])ss);
return ss.ToString();
}

public static string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}

static void CreateIfMissing(string path)
{
bool folderExists = Directory.Exists(path);
if (!folderExists)
Directory.CreateDirectory(path);
}

static IEnumerable<string> GetColumnNames(IDataReader reader)
{
foreach (DataRow row in reader.GetSchemaTable().Rows)
{
yield return (string)row["ColumnName"];
}
}

public static void Compress(DirectoryInfo directorySelected)
{
foreach (FileInfo fileToCompress in directorySelected.GetFiles())
{
using (FileStream originalFileStream = fileToCompress.OpenRead())
{
if ((File.GetAttributes(fileToCompress.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden & fileToCompress.Extension != ".gz")
{
using (FileStream compressedFileStream = File.Create(fileToCompress.FullName + ".gz"))
{
using (GZipStream compressionStream = new GZipStream(compressedFileStream,CompressionMode.Compress))
{
originalFileStream.CopyTo(compressionStream);
}
}
//FileInfo info = new FileInfo(directoryPath + "\\" + fileToCompress.Name + ".gz");
//Console.WriteLine("Compressed {0} from {1} to {2} bytes.",fileToCompress.Name, fileToCompress.Length.ToString(), info.Length.ToString());
}
}
}
}
}
}

 

 

 

Kaç Satır Kod Yazdığınızı Merak Ediyorsanız ?

Projelerinizde kaç satır kod yazdığınızı merak ediyorsanız ki ben etmiştim onun aşağıdaki ufak projeyi yazdım ( Kopyala + Yapıştır > Sonuç : ). Google üzerindeki araştırmalar sonucu bir klasör içerisindeki dosyaların Boyutlarını, Satır sayılarını, Karakter ve Kelime sayılarını basit bir şekilde ekrana döktüm.

 

Siz isterseniz birden fazla klasör seçimi de yapabilirsiniz. Proje örnek kodları ve projenin kaynak kodları aşağıda yer almaktadır. Proje C#.NET tabanlıdır. Neden diye sormayın en hızlı bununla çıkartabildim 🙂 Daha farklı yöntemler olabilir. Linç etmeyin 🙂

Form üzerinden seçilen klasörün içerisindeki dosyaları tek tek okuyup dosya yolu ile  birlikte datagrid nesnesine ekliyor.

            if (!Directory.Exists(@"" + textBox1.Text))
                return;
            dataGridView1.Rows.Clear();

            DirectoryInfo di = new DirectoryInfo(@""+textBox1.Text);
            FileInfo[] directories = null;
            try
            {
                // tüm klasörler içerisindeki hangi dosyaların hesaplanacağı -- hepsi seçildi.
                directories = di.GetFiles("*", SearchOption.AllDirectories); 
            }
            catch
            {

            }
            Int64 total = 0;
            foreach (var item in directories)
            {
                string FilePath = @"" + item.DirectoryName + "\\" + item.Name;
                var lineCount = File.ReadLines(FilePath).Count(); // satır sayısı
                Int64 WordsCount = 0; // kelime sayısı
                Int64 CharCount = 0; // karakter sayısı
                
                // dosyayı parçalara ayırıp kaç satır ve karakter olduğunu hesaplayacağız.
                string FileText = new System.IO.StreamReader(FilePath).ReadToEnd().Replace("\r\n", "\r");
                CharCount = FileText.Length;
                WordsCount = FileText.Split(' ').Length;
                // datagrid üzerine topladığımız bilgileri aktarıyoruz. BoyutHesapla fonksiyonu ile dosya boyutu hesaplanıyor ( b, kb, mb, gb vs )
                dataGridView1.Rows.Add(item.Name, item.DirectoryName.ToString().Replace(textBox1.Text, ""), BoyutHesapla( item.Length ), item.Length, lineCount, CharCount, WordsCount);
                total += item.Length;
            }
            label2.Text = ( dataGridView1.Rows.Count - 1 ).ToString();
            label4.Text = BoyutHesapla( total)+" ( "+total+" ) "; // toplam boyutu hesaplaıyoruz..

Yukarıdaki kodda yer alan BoyutHesapla fonksiyonu ise gelen boyutları byte, kilobyte, megabyte vb. cinsinden çevrilmesini sağllıyor.

        public static string BoyutHesapla(long gelenboyut)
        {
            if (gelenboyut >= 1073741824)
                return (gelenboyut / 1073741824) + " GB ";
            if (gelenboyut >= 1048576)
                return (gelenboyut / 1048576) + " MB ";
            if (gelenboyut >= 1024)
                return (gelenboyut / 1024) + " KB ";
            return gelenboyut + " B ";
        }

Proje Dosyalarını Buradan İndirebilirsiniz..

Mikrotik C# API Get Parse

Ufak bir proje için Mikrotik Firewall cihazlarından bilgileri çekmek için wiki.mikrotik.com tarafından hazır sınıfı ( Class ) kullanıyoruz.

Bu işlemleri hızlandırmak adına ufak bir Dictionary geri döndüren parse fonksiyonu hazırladık. Dışarıdan gönderilen MK class ı ile mik nesnesini otomatik olarak okuyup parçaladıktan sonra veriyi geriye dizi olarak döndürüyoruz. Bu diziyi örnekleyecek olursak bir tablo gibi geriye dönüyor. Satırlardan oluşuyor. Sütunlar için ise KEY -> VALUE şeklinde yapılanma mevcuttur.

public static Dictionary<int, Dictionary<string, string>> get_parse(MK mik)
{
Dictionary<int, Dictionary<string, string>> temp = new Dictionary<int, Dictionary<string, string>>();
int i = 0;
foreach (var item in mik.Read())
{
Dictionary<string, string> asd = new Dictionary<string, string>();
string[] tmp = item.Split('=');
for (int k = 0; k < tmp.Length; k += 2)
asd.Add(tmp[k], tmp[k + 1]);
temp[i] = asd;
i++;
}
temp.Remove(i - 1);
return temp;
}