Parsing machine-generated SQL in SQL Server [closed] - sql

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Ninjas,
this is a little bit hard.
I have an application's audit database based on SQL Server 2012. Inside there is a table with NTEXT column that contains raw text of sql queries. The queries are machine-like generated and they're not 'human friendly' readable (column is up to 20000 chars long, has a lot of aliases etc).
I am looking for a tool that allows me to parse that sql queries texts and will list all the columns and tables that are used in the query.
Up to now we've tried to figure out the algorithm on our own. But maybe there is a ready tool that will do it automaticly.
Thanks in advance for your help
Kaspar_

Create a new C# project. NuGet package id="Microsoft.SqlServer.TransactSql.ScriptDom" version="13.0.1601.5" targetFramework="net46"
Then you can do all kinds of cool things. Here is some sample code to capture parse errors. You will want to use the Parser that corresponds to your version of SQL Server naturally.
using Microsoft.SqlServer.TransactSql.ScriptDom;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace <EnterNamespaceHere>
{
public class ParsingError
{
public ParsingError(ParseError error)
{
Number = error.Number;
Offset = error.Offset;
Line = error.Line;
Column = error.Column;
Message = error.Message;
}
public int Column { get; private set; }
public int Line { get; private set; }
public string Message { get; private set; }
public int Number { get; private set; }
public int Offset { get; private set; }
public override string ToString()
{
return $"Error {Number} at offset {Offset} ({Line},{Column}): '{Message}'";
}
}
public static class TSqlHelper
{
public static bool ParseSyntax(string sql,
out IEnumerable<ParsingError> reportedErrors)
{
TSqlParser parser = new TSql130Parser(true);
IList<ParseError> errors;
using (StringReader rdr = new StringReader(sql))
{
parser.Parse(rdr, out errors);
}
if (errors != null && errors.Count > 0)
{
reportedErrors = errors.Select(
pe => new ParsingError(pe));
return false;
}
reportedErrors = null;
return true;
}
}
}

Related

The required column was not present in the results of a 'FromSql' operation. ( Stored procedure with Oracle)

wanted to call a stored procedure with oracle so after searching I found that
to do this I have to create a model and make context and of these things. but after doing that I got this out of nowhere
The required column was not present in the results of a 'FromSql' operation.
I'm working with asp core 2.2 and EF Core 2.2.1, now I'm getting these and I can't figure it out how to fix it or what is wrong .
I tried many things but nothing changes
Here are my files
Model
namespace test2._2.Models
{
public class CodeProc
{
public int ID { get; set; }
public int Erorrcode { get; set; }
public string ErrorMsg { get; set; }
}
}
Context
namespace test2._2.Models
{
public partial class ModelCodingContext : DbContext
{
public ModelCodingContext(DbContextOptions<ModelCodingContext> optionss)
: base(optionss)
{
}
public virtual DbSet<CodeProc> CodeProcs { get; set; }
}
}
the actual procedure to call and run and print the results
var result = await _dbCodingContext.CodeProcs.FromSql("begin FIX_CODING.GET_CLIENT_CODE12(245,255,:num1,:num2,:msg);end;", oracleParameter, oracleParameter2, oracleParameter3).ToArrayAsync();
ViewData["test"] += result.ToString();
Your required columns are: ID, Erorrcode, ErrorMsg
Check that the stored procedures returns exactly these columns. Account for case sensitivity, so 'ID' doesn't equal 'Id' as well as 'Errorcode' doesn't equal 'ErrorCode'.
Luckily, I solved my own by making the stored procedure to return a refcursor rather than 3 values and it went for good. but I wonder what to do if it returns values not a refcursor.

OOAD Design for furniture and testing [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
This question was asked in a interview.
A furniture can be made of one or more material. There are various furniture types like chair, table, sofa etc.
A furniture test is dependent on material & furniture type. Few tests are choakable, fire resistable, WithStands100KgWeight etc
Design this in OOAD. The design should follow Open Close principle and should be optimistic such that in future if new furniture is added, it should not need more code change.
Initially suggested with
class Furniture{
List<Material> materials;
boolean supportsTest(Test test);
}
class Chair extends Furniture{
boolean supportsTest(Test test){
// check material and based on type return true/false
}
Interviewer said that a furniture is a furniture, it should not say that it supports this test or not. Any alternative solution? Thanks.
Based on your description and the interviewer's comment, this is what comes to my mind:
// An interface so that it's separate from Furniture class
interface FurnitureTest {
bool IsSupportedBy(Furniture furniture);
}
// Sample test, can add as many as you like
class FireResistable : FurnitureTest {
public bool IsSupportedBy(Furniture furniture) {
return furniture.Type.Name == ! "Mirror" && /* just to use the Type property */
!furniture.HasMaterial(x => x == "Wood");
}
}
///
/// Other class definitions.
///
// Open to extension
class Chair : Furniture { /* additional properties */ }
class Table : Furniture { /* additional properties */ }
// Closed to modification
class Furniture {
public FurnitureType FurnitureType { get; private set; }
private IList<Material> materials;
public Furniture(FurnitureType type, IList<Material> materials) {
this.materials = materials;
}
public bool HasMaterial(string materialName) {
return materials.Any(x => x.Name == materialName);
}
}
class FurnitureType {
public string Name { get; set; }
// ...other properties
}
class Material {
public string Name { get; set; }
// other properties..
}

Redis caching with ServiceStack OrmLite and SQL Server persistence

We have a Web app (ASP.NET/C#) with SQL Server backend. We use ServiceStack OrmLite as our POCO Micro ORM. We would now like to extend a part of our app to cache frequently-read data (mainly a collection of POCO objects as values, with numeric keys). But I'm not sure how to go about integrating a simple caching solution (in-memory or Redis based) that works seamlessly with OrmLite and MSSQL as the Master database.
I've read about the ServiceStack Redis Client, MemoryCacheClient and Multi nested database connections (OrmLiteConnectionFactory), but I couldn't find any examples, tutorial or code samples to learn more about implementing caching that works with OrmLite.
Any suggestions or links will be helpful and much appreciated.
I use this extension to help simplify the integration between the db and the cache.
public static class ICacheClientExtensions
{
public static T ToResultUsingCache<T>(this ICacheClient cache, string cacheKey, Func<T> fn, int hours = 1) where T : class
{
var cacheResult = cache.Get<T>(cacheKey);
if (cacheResult != null)
{
return cacheResult;
}
var result = fn();
if (result == null) return null;
cache.Set(cacheKey, result, TimeSpan.FromHours(hours));
return result;
}
}
public class MyService : Service
{
public Data Get(GetData request)
{
var key = UrnId.Create<Data>(request.Id);
Func<Data> fn = () => Db.GetData(request.Id);
return Cache.ToResultUsingCache(key, fn);
}
[Route("/data/{id}")]
public class GetData: IReturn<Data>
{
public int Id{ get; set; }
}
}
You'd need to implement the caching logic yourself, but it's not much work - here's a pseudocode example:
public class QueryObject
{
public DateTime? StartDate { get; set; }
public string SomeString { get; set; }
}
public class Foo
{
public DateTime DateTime { get; set; }
public string Name { get; set; }
}
public class FooResponse
{
public List<Dto> Data { get; set; }
}
public FooResponse GetFooData(QueryObject queryObject)
{
using (var dbConn = connectionFactory.OpenDbConnection())
using (var cache = redisClientsManager.GetCacheClient())
{
var cacheKey = string.Format("fooQuery:{0}", queryObject.GetHashCode()); //insert your own logic for generating a cache key here
var response = cache.Get<Response>(cacheKey);
//return cached result
if (response != null) return response;
//not cached - hit the DB and cache the result
response = new FooResponse()
{
Data =
dbConn.Select<Foo>(
x => x.DateTime > queryObject.StartDate.Value && x.Name.StartsWith(queryObject.SomeString)).ToList()
};
cache.Add(cacheKey, response, DateTime.Now.AddMinutes(15)); //the next time we get the same query in the next 15 mins will return cached result
return response;
}
}
Have you checked Service stack caching wiki. It gives detailed info about caching. Now in your case from the details you are providing I can say that you can go for any kind of caching. As of now it will not make any difference.
PS: A piece of advice caching should be done when there is no option or the only thing pending in application. Because it comes with it's own problem is invalidating caching, managing and all that. So, if you application is not too big, just leave it for now.

OData / WCF Data Service not working with complex type

I'm brand new to OData and WCF data services so this might be an easy problem. I'm using VS Web Developer Express 2010 where I have a very simple WCF Data Service hosted in a console app. It's returning an IQuerable collection of a simple 'Study' class from a repository (located in a separated dll project), which in turn retrieves 'Study' classes from a db project in another dll (so 3 projects in the solution).
I also have an 'Experiment' class in the db project and there can be multiple Experiments in a Study. When I exclude the Experiment class from the Study everything works and I get data coming back. The problem happens when I add a List collection to the Study class, then I get a runtime error when I try to run the service. In Firebug the error is '500 Internal Server Error', and the message in the browser is 'Request Error. The server encountered an error processing the request. See server logs for more details.'
I have IIS 7 and I also just installed IIS 7.5 but again it's brand new to me, so I can't figure out where the service is hosted or where to view the server / web logs. There are only IIS 7 logs visible in 'C:\inetpub\logs\LogFiles\W3SVC1'. The VS web server (Cassini) doesn't start when I run the app, so this suggests it's being hosted in IIS 7.5 (?).
So
- how do I return child classes / complex objects?
- how do I know where my service is hosted and where can I find the server logs?
Here's the host app:
using MyStudyRepository;
using MyStudyDB;
namespace MyStudyService
{
public class Program
{
public static void Main(string[] args)
{
string serviceAddress = "http://localhost:998";
Uri[] uriArray = { new Uri(serviceAddress) };
Type serviceType = typeof(StudyDataService);
using (var host = new DataServiceHost(serviceType,uriArray))
{
host.Open();
Console.WriteLine("Press any key to stop service");
Console.ReadKey();
}
}
}
public class StudyDataService : DataService<StudyRepository>
{
public static void InitializeService(IDataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
}
}
}
Here's the repository:
using MyStudyDB;
namespace MyStudyRepository
{
public class StudyRepository
{
List<Study> _List = new List<Study>();
//Add constructor to populate myStudies list on creation of class
public StudyRepository()
{
for (int i = 1; i < 5; i++)
{
Study myStudy = new Study() { ID = i, StudyOwnerId = i, StudyName = "Study" + i.ToString() /*, Experiments = null */ };
_List.Add(myStudy);
}
}
public IQueryable<Study> Studies
{
get
{
return _List.AsQueryable<Study>();
}
}
}
}
And here's the DB:
namespace MyStudyDB
{
public class Study
{
public int ID { get; set;}
public int StudyOwnerId { get; set; }
public string StudyName { get; set; }
//public List<Experiment> Experiments { get; set; }
}
public class Experiment
{
public int ID { get; set; }
public string Name { get; set; }
public int StudyId { get; set; }
}
}
To debug the WCF Data Service please refer to this blog post: http://blogs.msdn.com/b/phaniraj/archive/2008/06/18/debugging-ado-net-data-services.aspx
As to why the collection of Experiment doesn't work, there are two reasons:
The Experiment class is not recognized as an entity type because there's no entity set for it. (Entity set is the IQueryable property on your repository class, which you don't have). As a result the Experiment class is only recognized as a complex type.
The currently released version of WCF Data Services doesn't support MultiValues, MultiValue is effectively a collection of primitive or complex types.
So you have two way to "fix" this. Either make sure that Experiment is in fact an entity, by adding IQueryable property on your repository class.
Or use the latest CTP (http://blogs.msdn.com/b/astoriateam/archive/2011/06/30/announcing-wcf-data-services-june-2011-ctp-for-net4-amp-sl4.aspx) which does support MultiValues.
Thanks! And I guess it is missing the DataServiceKey attribute on the class as follows:
[DataServiceKey("ID")]
public class Study
{
.....
}

Mismatched group tags detected in message - protobuf-net

I’m quite new to Silverlight. I’m working for a project which mainly depends on Serialization and Deserialization.
Formerly, for WPF I was comfortable with Serializable classes. For silverlight, I found protobuf would be quite useful. But, I'm troubled with this exception. I don't know what causes this problem. Please help me out.
I'm using Silverlight 3.0.
protobuf-net r282
Please find the code which I’m using.
[ProtoContract]
public class Report
{
public Report()
{
}
[ProtoMember(1)]
public SubReports SubReports { get; set; }
}
[ProtoContract]
public class SubReports
: List<SubReport>
{
public SubReports()
{
}
[ProtoMember(1)]
public SubReport SubReport { get; set; }
}
[ProtoContract]
public class SubReport
{
public SubReport()
{
}
[ProtoMember(1)]
public string Name { get; set; }
}
The Code I’m using to de-serialize is
public static T Deserialize<T>(Byte[] bytes) where T
: Report
{
return ProtoBuf.Serializer.Deserialize<T>(new MemoryStream(bytes));
}
My sample XML looks similar to
Report
...SubReports
...SubReport Name=”Q1 Report”
...SubReport Name=”Q2 Report”
...SubReport Name=”Q3 Report”
...SubReport Name=”Q4 Report”
Thanks in advance.
Vinodh
(note: I couldn't reproduce the "group tags" issue; see edit history for my first thoughts on this, now removed; if you can help me reproduce this I'd be grateful)
The problem is SubReports. You have defined this both as a list and as a serialization entity ([ProtoContract]); the latter takes precedence, so it was trying to serialize the single sub-report on the list (which is always null?).
If you change this to:
// note no attributes, no child property
public class SubReports : List<SubReport> { }
or if you remove it completely and make Report.SubReports a List<SubReport> it should work fine. The following works:
static void Main() {
byte[] blob;
// store a report
using (MemoryStream ms = new MemoryStream()) {
Report report = new Report {
SubReports = new List<SubReport> {
new SubReport { Name="Q1"},
new SubReport { Name="Q2"},
new SubReport { Name="Q3"},
new SubReport { Name="Q4"},
}
};
Serializer.Serialize(ms, report);
blob = ms.ToArray();
}
// show the hex
foreach (byte b in blob) { Console.Write(b.ToString("X2")); }
Console.WriteLine();
// reload it
using (MemoryStream ms = new MemoryStream(blob)) {
Report report = Serializer.Deserialize<Report>(ms);
foreach (SubReport sub in report.SubReports) {
Console.WriteLine(sub.Name);
}
}
}
Displaying the blob:
0A040A0251310A040A0251320A040A0251330A040A025134