I'm using FileNet P8 Content Engine 5.5.x with the Java API to construct an ad-hoc query using SearchSQL. Creating a select statement based off of the Document class is straight-forward:
SearchSQL sql = new SearchSQL();
String selectList = "d.This, d.Id, d.Name, d.ClassDescription";
sql.setSelectList(selectList);
sql.setFromClauseInitialValue("Document", "d", true);
SearchScope scope = new SearchScope(conn.getObjectStore());
RepositoryRowSet rows = scope.fetchRows(sql, 8, null, null);
Note: The statement above is using the ClassDescription object, which you 'could' use but it would require navigating the object to get to the SymbolicName. You would also have to be carefull and craft the property filter to not cause a round-trip back to the server.
However, adding a join to the ClassDefinition class has not been successful:
SearchSQL sql = new SearchSQL();
String selectList = "d.This, d.Id, d.Name, d.ClassDescription";
sql.setSelectList(selectList);
sql.setFromClauseInitialValue("Document", "d", true);
sql.setFromClauseAdditionalJoin(JoinOperator.INNER,"ClassDefinition","cd","d.This", JoinComparison.EQUAL,"cd.Id",false);
SearchScope scope = new SearchScope(conn.getObjectStore());
RepositoryRowSet rows = scope.fetchRows(sql, 8, null, null);
Note: This version suffers from the same problem as the first one.
The problem is what to use as the join variable ("d.This") from the Document class, everything I've tried has thrown some type of SQL Syntax Exception. The kicker is that if I had access to the Oracle database I believe the join is simple.
SELECT dv.object_id, dv.u2e_documenttitle, cd.symbolic_name
FROM DocVersion dv
INNER JOIN ClassDefinition cd ON
dv.object_class_id = cd.object_id
At the end of the day, what I'm try to achieve is to get the Symbolic Name of the ClassDefinition class in the returned result set.
Having read most of the online API Documentation and still not getting any closer to an answer, I opened a ticket with IBM Support. Here is the correct way to join the Document Class to the Class Definition Class via the ad-hock SQL Query API
var sql = new SearchSQL();
sql.setFromClauseInitialValue("Document", "d", true);
sql.setFromClauseAdditionalJoin(JoinOperator.INNER, "ClassDefinition","cd","d.ClassDescription", JoinComparison.EQUAL,"cd.This",true);
var scope = new SearchScope(os);
var pf = new PropertyFilter();
pf.addIncludeProperty(new FilterElement(1, null, null, PropertyNames.THIS, null));
pf.addIncludeProperty(new FilterElement(1, null, null, PropertyNames.ID, null));
pf.addIncludeProperty(new FilterElement(1, null, null, "DocumentTitle", null));
pf.addIncludeProperty(new FilterElement(1, null, null, PropertyNames.MIME_TYPE, null));
pf.addIncludeProperty(new FilterElement(1, null, null, PropertyNames.DATE_CREATED, null));
pf.addIncludeProperty(new FilterElement(1, null, null, PropertyNames.SYMBOLIC_NAME, null));
pf.addIncludeProperty(new FilterElement(1, null, Boolean.FALSE, PropertyNames.CLASS_DESCRIPTION, null));
pf.addIncludeProperty(new FilterElement(1, null, Boolean.FALSE, PropertyNames.CLASS_DEFINITION, null));
pf.addIncludeProperty(new FilterElement(1, null, Boolean.FALSE, PropertyNames.PROPERTY_DEFINITIONS, null));
pf.addIncludeProperty(new FilterElement(1, null, null, PropertyNames.CONTENT_ELEMENTS_PRESENT, null));
RepositoryRowSet rows = scope.fetchRows(sql, 256, pf, null);
Related
I can't get this simple query right. I need to join my adresses table to my annonces table.
I supose this should be farly strait forward but I simply can't get it to work.
I firstly made my adresse table object like this
class AdressesTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Annonces', [
'foreignKey' => 'annonceId',
'joinType' => 'INNER',
]);
}
}
Then in my annonces controller I tryed to join the adresses like this
public function view($id = null)
{
if (!$id) {
throw new NotFoundException(__('Annonce invalide!'));
}
$query = $this->Annonces->find('all', ['contain' => ['Adresses']])->where(['id' => $id]);
$annonce = $query->firstOrFail();
$this->set(compact('annonce'));
}
But then I got this error :
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Adresses.annonce_id' in 'where clause'
Witch I don't understand why I got it since I have defined my foreign key in the AdressesTable class.
The query I would like to have at the end would look like this
SELECT *
FROM annonces
INNER JOIN adresses ON adresses.annonceId = annonces.id
WHERE annonces.id = #param
*PS. I know it wont be select * but rather select [all my column]*
EDIT : My table schema are as following
CREATE TABLE annonces(
id INT NOT NULL AUTO_INCREMENT, #PK
startDate DATE NOT NULL,
endDate DATE NOT NULL,
title VARCHAR(128) NOT NULL,
descript TEXT NOT NULL,
infoSupplementaire TEXT NULL,
premium BIT NOT NULL,
clientId INT NOT NULL, #FK
categorieId INT NOT NULL, #FK
CONSTRAINT pk_annonces_id PRIMARY KEY (id),
CONSTRAINT fk_annonces_clientId FOREIGN KEY (clientId) REFERENCES clients(id),
CONSTRAINT fk_annonces_categorieId FOREIGN KEY (categorieId) REFERENCES categories(id)
);
CREATE TABLE adresses(
id INT NOT NULL AUTO_INCREMENT, #PK
latitude DECIMAL(11,7),
longitude DECIMAL(11,7),
adresse VARCHAR(512),
annonceId INT NOT NULL, #FK
CONSTRAINT pk_adresses_id PRIMARY KEY (id),
CONSTRAINT fk_adresses_annonceId FOREIGN KEY (annonceId) REFERENCES annonces(id)
)
I solved my problem by renaming my column folowing cakephp convention and using any of the code from this answer
You can try
$query = $this->Annonces->find('all', ['contain' => ['Adresses']])->where(['Annonces.id' => $id]);
$annonce = $query->firstOrFail();
OR
public function view($id = null)
{
if (!$id) {
throw new NotFoundException(__('Annonce invalide!'));
}
$annonceEntity = $this->Annonces->get($id);
$query = $this->Annonces->find('all', ['contain' => ['Adresses']])->where(['Annonces.id' => $annonceEntity->id]);
$annonce = $query->firstOrFail();
$this->set(compact('annonce'));
}
I created a .sqlite file in ios programatically like below by enabling pragma foreignkeys ON
NSFileManager *theFileManager = [NSFileManager defaultManager];
if ([theFileManager fileExistsAtPath:[self getDatabasePath]] == NO)
{
char *theError;
const char *databasePath = [[self getDatabasePath] UTF8String];
const char *enableForienKey = [#"PRAGMA foreign_keys = ON;" UTF8String];
if (sqlite3_open(databasePath, &mDatabase) == SQLITE_OK)
{
if (sqlite3_exec(mDatabase, enableForienKey, NULL, NULL, &theError)!=SQLITE_OK)
{
DEBUGLOG(kCreateTableError,sqlite3_errmsg(mDatabase));
}
sqlite3_close(mDatabase);
}
else {
DEBUGLOG(KFailedToCreateDBFile);
}
}
Pragma foreign key is enabling but, I created two tables like below with create queries including ON DELETE CASCADE
// First table Create query
#"CREATE TABLE IF NOT EXISTS Session (sessionAppID INTEGER PRIMARY KEY NOT NULL , sessionID VARCHAR(255) NOT NULL, userAppID INTEGER, deviceAppID INTEGER NOT NULL, sessionStartTime VARCHAR(255) NOT NULL, sessionEndTime VARCHAR(255), sessionCreatedDateTime VARCHAR(200) NOT NULL,sessionUpdatedDateTime VARCHAR(200) NOT NULL, sessionFailureCount INTEGER NOT NULL,sessionStatus INTEGER NOT NULL, FOREIGN KEY(userAppID) REFERENCES User(userAppID), FOREIGN KEY(deviceAppID) REFERENCES Device(deviceAppID))"
//Second table which is child of first table query
#"CREATE TABLE IF NOT EXISTS EventLog (eventLogAppID INTEGER PRIMARY KEY NOT NULL , eventGUID VARCHAR(255) NOT NULL, sessionAppID INTEGER NOT NULL , eventName VARCHAR(255) NOT NULL, eventGroupGUID VARCHAR(255), eventParentGUID VARCHAR(255), eventCategory INTEGER NOT NULL,eventStartTime VARCHAR(255) NOT NULL, eventEndTime VARCHAR(255) ,eventDuration VARCHAR(255),eventType INTEGER NOT NULL,eventCreatedDateTime VARCHAR(200) NOT NULL,eventUpdatedDateTime VARCHAR(200) NOT NULL,eventFailureCount INTEGER NOT NULL,eventStatus INTEGER NOT NULL, FOREIGN KEY(sessionAppID) REFERENCES Session(sessionAppID)ON DELETE CASCADE)"
On deleting the session record, Only session record is deleting eventLog records are not deleting, Can any one please help on this, what will be the problem.By the way I am using sqlite3 version 3.7.1
See http://www.sqlite.org/foreignkeys.html#fk_enable. Note that you need to enable foreign keys for each connection.
Presumably you are creating a new connection to perform the delete query. Update your code so every time you open a db connection, you set the pragma as needed.
I was using singleton instance of SQLiteAsyncConnection in Xamarin.Forms, but anyways had to call "PRAGMA foreign_keys=ON;" before each DeleteAsync method call. Calling it once after opening the connection didn't work for me. To sum up what #rmaddy and #Karthik Mitta tried to jointly say
For monitoring and investigation purpose I would like to have the result from sp_WhoIsActive (especially the query plan which is xml column) to be stored into table, due to restriction I would have to store the result on another server.
When trying this using link server the error pop:
Xml data type is not supported in distributed queries. Remote object 'IROWSET' has xml column(s)
How can this be achieved?
First you need to get the schema for your parameters as given below:
DECLARE #createTableSchema VARCHAR(MAX)
EXEC sp_WhoIsActive
#filter = '',
#filter_type = 'session',
#not_filter = '',
#not_filter_type = 'session',
#show_own_spid = 0,
#show_system_spids = 0,
#show_sleeping_spids = 0,
#get_full_inner_text = 0,
#get_plans = 1,
#get_outer_command = 0,
#get_transaction_info = 1,
#get_task_info = 1,
#get_locks = 0,
#get_avg_time = 0,
#get_additional_info = 1,
#find_block_leaders = 0,
#delta_interval = 0,
#output_column_list = '[dd%][session_id][sql_text][sql_command][login_name][wait_info][tasks][tran_log%][cpu%][temp%][block%][reads%][writes%][context%][physical%][query_plan][locks][%]',
#sort_order = '[start_time] ASC',
#format_output = 1,
#destination_table = '',
#return_schema = 1,
#schema = #createTableSchema OUTPUT,
#help = 0;
SELECT #createTableSchema
GO
Once you get the schema, use that to create table as given below:
CREATE TABLE dbo.AuditTableName (
[dd hh:mm:ss.mss] VARCHAR(8000) NULL
,[session_id] SMALLINT NOT NULL
,[sql_text] XML NULL
,[login_name] NVARCHAR(128) NOT NULL
,[wait_info] NVARCHAR(4000) NULL
,[tran_log_writes] NVARCHAR(4000) NULL
,[CPU] VARCHAR(30) NULL
,[tempdb_allocations] VARCHAR(30) NULL
,[tempdb_current] VARCHAR(30) NULL
,[blocking_session_id] SMALLINT NULL
,[reads] VARCHAR(30) NULL
,[writes] VARCHAR(30) NULL
,[physical_reads] VARCHAR(30) NULL
,[query_plan] XML NULL
,[used_memory] VARCHAR(30) NULL
,[status] VARCHAR(30) NOT NULL
,[tran_start_time] DATETIME NULL
,[open_tran_count] VARCHAR(30) NULL
,[percent_complete] VARCHAR(30) NULL
,[host_name] NVARCHAR(128) NULL
,[database_name] NVARCHAR(128) NULL
,[program_name] NVARCHAR(128) NULL
,[additional_info] XML NULL
,[start_time] DATETIME NOT NULL
,[login_time] DATETIME NULL
,[request_id] INT NULL
,[collection_time] DATETIME NOT NULL
)
Now, mention the Audit table name in the sp_whoisactive call. The data from the sp_whoisactive will be stored in the table.
EXEC sp_WhoIsActive
#filter = '',
#filter_type = 'session',
#not_filter = '',
#not_filter_type = 'session',
#show_own_spid = 0,
#show_system_spids = 0,
#show_sleeping_spids = 0,
#get_full_inner_text = 0,
#get_plans = 1,
#get_outer_command = 0,
#get_transaction_info = 1,
#get_task_info = 1,
#get_locks = 0,
#get_avg_time = 0,
#get_additional_info = 1,
#find_block_leaders = 0,
#delta_interval = 0,
#output_column_list = '[dd%][session_id][sql_text][sql_command][login_name][wait_info][tasks][tran_log%][cpu%][temp%][block%][reads%][writes%][context%][physical%][query_plan][locks][%]',
#sort_order = '[start_time] ASC',
#format_output = 1,
#destination_table = 'dbo.AuditTableName',
#return_schema = 0,
#schema = NULL,
#help = 0;
GO
You can also refer to detailed article on this by Adam Mechanic himself. Capturing Output of Whoisactive
It seems like you have a bunch of SQL servers and want to send all results to one central global production audit server. This is the method I've used. This allows you to add additional columns, such as SERVER NAME. Linked Servers simply does not support the XML data type, it must be a minor modified solution.
You have to convert the XML column into a VARCHAR(MAX) and store the Query Plan as a VARCHAR(MAX) on the global Table in your other Server. Do the following steps
Create a <table> with the sp_WhoIsActive schema with the XML column
Run INSERT INTO <table>... EXEC sp_WhoIsActive to populate that table in one statement
Now query the <table> while converting XML to VARCHAR(MAX)
Insert the results of that converted XML to VARCHAR into the table in your Linked Server
Doing this in a SQL Agent Job also works too.
Brent Ozar has an color excellent example located here. Look at step one to create a destination table.
However a much more detailed example is located here by Adam Machanic who I believe wrote this great diagnostic proc and released it to the public. Thanks Adam!
Basically you have to use the parameters #return_schema=1 and #schema
as an output variable. Afterwards you do a replace of ''
with a table of your choice. Then execute it as dynamic SQL.
I am executing following code from c# MVC3 but getting error on bulkCopy.WriteToServer "Cannot access destination table '[#tablename]'"
Any one have idea what is wrong into following code. I went to few solution but doesn't work here.
var uniqueID = Guid.NewGuid();
AsclipeiousMembercode = AsclipeiousMembercode.Distinct().ToList();
System.Data.DataTable datatable = new System.Data.DataTable();
datatable.Columns.Add("Guid", uniqueID.GetType());
datatable.Columns.Add("MemberCode");
datatable.Columns.Add("DateCreated", DateTime.Now.GetType());
var connectionString = Aurora.Customers.Data.Properties.Settings.Default.AuroraCustomerDBConnectionString;
using (System.Data.SqlClient.SqlBulkCopy bulkCopy =
new System.Data.SqlClient.SqlBulkCopy(connectionString, System.Data.SqlClient.SqlBulkCopyOptions.KeepIdentity))
{
var tableName = "[#MemberCode_TempTable_" + uniqueID.ToString().Replace("-", "") + "]";
var commandText = "CREATE TABLE " + tableName + " ([id] [int] IDENTITY(1,1) NOT NULL,[Guid] [uniqueidentifier] NOT NULL,[MemberCode] [nvarchar](max) NOT NULL, [DateCreated] [datetime] NOT NULL)";
Db.ExecuteCommand(commandText);
Db.SubmitChanges();
bulkCopy.DestinationTableName = tableName;
bulkCopy.ColumnMappings.Add("Guid", "Guid");
bulkCopy.ColumnMappings.Add("MemberCode", "MemberCode");
bulkCopy.ColumnMappings.Add("DateCreated", "DateCreated");
datatable = dbMemberCodeTempTable.ToDataTable();
bulkCopy.WriteToServer(datatable);
}
How do I create the ELMAH SQL Server database? I added it to my ASP.NET MVC project through NuGet and don't have the sql script on my machine.
The DDL script is linked from the Elmah downloads page. No need to trawl the source tree.
(Why it's not bundled with the NuGet escapes me)
I found the script in source control: https://code.google.com/p/elmah/source/browse/src/Elmah.SqlServer/SQLServer.sql
Run that script on the database you are using to create the database structures for Elmah.
For a code first migration scenario, I found the this article very helpful.
First run Add-Migration AddElmah command in 'Package Manager Console'. This will create a file under Migration folder. This file will contain AddElmah class with to functions Up() and Down(). Replaced these two functions with below code:
public override void Up()
{
Sql(#"CREATE TABLE [dbo].[ELMAH_Error]
(
[ErrorId] UNIQUEIDENTIFIER NOT NULL,
[Application] NVARCHAR(60) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Host] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Type] NVARCHAR(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Source] NVARCHAR(60) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Message] NVARCHAR(500) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[User] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[StatusCode] INT NOT NULL,
[TimeUtc] DATETIME NOT NULL,
[Sequence] INT IDENTITY(1, 1) NOT NULL,
[AllXml] NTEXT COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ");
Sql("EXEC('ALTER TABLE [dbo].[ELMAH_Error] WITH NOCHECK ADD CONSTRAINT[PK_ELMAH_Error] PRIMARY KEY([ErrorId])')");
Sql("EXEC('ALTER TABLE [dbo].[ELMAH_Error] ADD CONSTRAINT[DF_ELMAH_Error_ErrorId] DEFAULT(NEWID()) FOR[ErrorId]')");
Sql(#"EXEC('CREATE NONCLUSTERED INDEX [IX_ELMAH_Error_App_Time_Seq] ON [dbo].[ELMAH_Error]
(
[Application] ASC,
[TimeUtc] DESC,
[Sequence] DESC
)')");
Sql(#"EXEC('CREATE PROCEDURE [dbo].[ELMAH_GetErrorXml] (#Application NVARCHAR(60), #ErrorId UNIQUEIDENTIFIER) AS
SET NOCOUNT ON
SELECT [AllXml] FROM [ELMAH_Error] WHERE [ErrorId] = #ErrorId AND [Application] = #Application')");
Sql(#"EXEC('CREATE PROCEDURE [dbo].[ELMAH_GetErrorsXml]
(#Application NVARCHAR(60), #PageIndex INT = 0, #PageSize INT = 15, #TotalCount INT OUTPUT)
AS
SET NOCOUNT ON
DECLARE #FirstTimeUTC DATETIME
DECLARE #FirstSequence INT
DECLARE #StartRow INT
DECLARE #StartRowIndex INT
SELECT #TotalCount = COUNT(1) FROM [ELMAH_Error] WHERE [Application] = #Application
SET #StartRowIndex = #PageIndex * #PageSize + 1
IF #StartRowIndex <= #TotalCount
BEGIN
SET ROWCOUNT #StartRowIndex
SELECT #FirstTimeUTC = [TimeUtc], #FirstSequence = [Sequence] FROM [ELMAH_Error]
WHERE [Application] = #Application ORDER BY [TimeUtc] DESC, [Sequence] DESC
END
ELSE
BEGIN
SET #PageSize = 0
END
SET ROWCOUNT #PageSize
SELECT
errorId = [ErrorId],
application = [Application],
host = [Host],
type = [Type],
source = [Source],
message = [Message],
[user] = [User],
statusCode = [StatusCode],
time = CONVERT(VARCHAR(50), [TimeUtc], 126) + ''Z''
FROM [ELMAH_Error] error WHERE [Application] = #Application AND [TimeUtc] <= #FirstTimeUTC
AND [Sequence] <= #FirstSequence ORDER BY [TimeUtc] DESC, [Sequence] DESC FOR XML AUTO')");
Sql(#"EXEC('CREATE PROCEDURE [dbo].[ELMAH_LogError] (#ErrorId UNIQUEIDENTIFIER, #Application NVARCHAR(60), #Host NVARCHAR(30),
#Type NVARCHAR(100), #Source NVARCHAR(60), #Message NVARCHAR(500), #User NVARCHAR(50), #AllXml NTEXT, #StatusCode INT,
#TimeUtc DATETIME) AS
SET NOCOUNT ON
INSERT INTO [ELMAH_Error] ([ErrorId], [Application], [Host], [Type], [Source], [Message], [User], [AllXml], [StatusCode], [TimeUtc])
VALUES (#ErrorId, #Application, #Host, #Type, #Source, #Message, #User, #AllXml, #StatusCode, #TimeUtc)')");
}
public override void Down()
{
Sql("EXEC('DROP PROCEDURE [ELMAH_GetErrorXml]')");
Sql("EXEC('DROP PROCEDURE [ELMAH_GetErrorsXml]')");
Sql("EXEC('DROP PROCEDURE [ELMAH_LogError]')");
Sql("Drop table ELMAH_Error");
}
Now when you will execute Update-Database command in "Package Manager Console", ELMAH_Error table and associated procedures will be created in the database.
Elmah source has been moved to GitHub. The current file for SQL Server is located in the SqlErrorLog repo under the Elmah organization.
SqlErrorLog: /src/SQLServer.sql
Other database scripts can be found by searching errorlog under the Elmah GitHub organization. e.g. https://github.com/elmah?q=errorlog