How to Structure an ASP.NET website with over 1,300 Articles/Quotes - sql-server-2005

Good Morning All,
I have loaded over 1,300 blurbs into my client's database with table schema of BlurbID, Seq, Content, Keywords. A separate database table will contain vote details (voteID, BlurbID, Seq, VoteDate). His intent is to have a blurb website that serves up humorous quotes. Users must vote for the first blurb before being allowed to see the next one, and so forth.
The client will modify the blurb table as needed to re-sequence the blurbs. He wants the blurbs displayed on content pages in the website according to the value of the SEQ field in the Blurbs table. Thus, the entry with SEQ=1 will be the first Blurb displayed on the site etc. Users will be required to vote using a radiobuttonlist for each blurb before being allowed to see the next blurb.
Question: Is it advisable to use one content page (default.aspx) to serve up the blurbs? If I do that, how do I structure a stored procedure to select the blurbs according to the SEQ field in the blurb table? Conversely, do I create content pages for each of the 1,300 blurbs? If I use one content page, what would the TSQL look like to iterate through the blurbs according to the SEQ field after a vote is cast for each blurb? Pseudo code would be: if radiobuttonlist.value >0 then select blurb id, seq, blurbcontent, keywords from blurbs where seq = current seq +1
Finally, for SEO purposes, should I output the keywords database field to a hidden field on the content page?
If you have written this type of site before, I would greatly appreciate your insight and guidance.
Thanks,
Sid

Learn asp.net ;) Seriously - especially the ASP.NET routing added some time ago, and while you are at it, learn MVC.
There is no sense to even have more than one view on the data. It is all the same.
Years ago, those who did not know made something like "/default.aspx/id=1
Years ago, those who DID read the documentation wrote something like "/content.ashx/112
Today everyone should use URL routing and write something like /sometitle.html for everything, and use the routing mechanism to route that call to a program module (page, view, whatever) that generates the html.
I suggest pulling the title from the database (or use the first x words) so you have some textual reference, not jut an ID.
Now, database
What do you mean with "how do I structure a stored procedure to". This is similar to "how do I structure a pizza delivery service to deliver pizza tonno". The stored procedure sturecture should depend on your coding guidelines, not on what data you retrieve- this is for the code part in the structure. And that will depend a lot on your needs, which obviously are - given from the site design.
Why do you think you even need a stored procedure here? ;)

Related

Cosmos DB where condition by external document

I have a following structure of document (omiting all with underscore prefix like _self)
{
"id": "c5055e2b-efb2-4c86-907d-a0beb1dca4dc",
"Name": "John Johnson",
"partitionKey": "0ecdb989-01c6-4f11-9fd2-3e1dcc1c8cb9",
"FKToBeDeleted": "FK_c5055e2b-efb2-4c86-907d-a0beb1dca4dc_ToBeDeleted",
}
And as You can see there is a field named FKToBeDeleted and I use this to mark document, but it has to be as a reference, because in my app may occure kind of database concurrency, because 1st app can GET document, process it, and 2nd app can update document during processing and 1st one will not see any changes, because downloading again huge document and updating it is RU consuming, so I wanted to reduce the cost. Going further, I created a document for this.
{
"id": "FK_c5055e2b-efb2-4c86-907d-a0beb1dca4dc_ToBeDeleted",
"partitionKey": "0ecdb989-01c6-4f11-9fd2-3e1dcc1c8cb9",
"ToBeDeleted": false,
}
And now there is a problem, because my front-end app does not want to display any ToBeDeleted documents. This kinda cheats the user, because I just mark it as deleted but later delete the document.
Now the question is how the SQL query should look like? Previously it was like the following query, because r.ToBeDeleted was boolean.
SELECT r.id, r.Name, r.AddedAt, r._ts
FROM ROOT r
WHERE
(NOT(r.ToBeDeleted))
ORDER BY r.AddedAt desc
Now FKToBeDeleted is only a reference to another document, but the ID is in r.FKToBeDeleted, so I tried some nested SELECT but it didn't work.
Any suggestions what is the right way to achieve that?
EDIT (clarification)
Let's have a following situation.
There are two apps (you can also treat them as threads) which uses the same Cosmos DB instance.
STEP 1 - is a moment of start of processing some data, but database document is needed, so it gets that and on the right side you can see current document (but in fact only ToBeDeleted is interesting here).
STEP 2 - is a moment, when user wants to remove this processed item, because he is no longer interested of its results, but database document is also required here, so again there is a GET.
STEP 3 - is a moment, when job of soft delete is done and there is a need to update database document, and the field is set to true.
STEP 4 - is a moment, when processing is over of common flow and at the end there is update of the document. BUT, Application 2 downloaded it before STEP 3, and it's overriding things that Application 1 did, which is bad.
So I made a solution for that.
As you can see, the steps are the same, but instead of updating the same document, I update a referenced document, so I don't have a problem with overriding data.
Now, the problem is how to make a SQL query to join two documents, so the FK_1 id will be replaced of the value of ToBeDeleted field in another document.
According to this article there is no possibility to join two documents, which of course does not help me at all, yet closes the topic.
JOIN keyword exists in the language, but it is used to “unfold” nested containers, there is no way to join different documents.
Perhaps, you can use subquery instead of JOIN.
https://learn.microsoft.com/en-us/azure/cosmos-db/sql-query-subquery#mimic-join-with-external-reference-data

Where in the Sitefinity database is content stored?

I've successfully migrated 1,000s of news items and other content from Sitefinity 5 to Wordpress after hours of excruciating analysis and sheer luck with guessing but have a few items that are still left over. Specifically the pages. I know a lot of the content is stored in very obscure ways but there has to be somebody who has done this before and can steer me in the right direction.
My research (and text-search against the DB) has found the page titles etc but when I search the content I get nothing. My gut tells me that the content is being stored in binary form, can anyone confirm if this is the case?
Sitefinity documentation is only helpful if you're a .net developer who has a site set up in Visual Studio (as far as I've seen).
This is probably the most obfuscated manner of storing content that I've ever encountered. After performing text searches against the database I've finally found where the content is stored but it's not a simple process to get it out.
Pages' master record appears to be sf_page_node, there are related tables:
sf_object_data (page_id is related to sf_page_node.content_id)
sf_draft_pages (page_id is related to sf_page_node.content_id)
sf_page_data (content_id is related to sf_page_node.content_id)
sf_control_properties (control_id is related to sf_object_data.id)
So you could get the info you need with a query like this:
select * from
[sf_page_node]
join sf_object_data on sf_page_node.content_id = sf_object_data.page_id
join sf_control_properties on sf_object_data.id = sf_control_properties.control_id
Other things to consider:
the parent_id field is related to the sf_page_node table, so if you're writing a script, be sure to query this as well
the page may have a banner image, you will pick up the "place_holder" value as 'BannerHolder' with a caption of "Image" The image may be stored as blobs in sf_media_content, you should handle this separately. The "nme" value of 'ImageId' will have a GUID in the "val" column. You can query sf_media_content with this value as "content_id" the actual binary data is stored in sf_chunks, they relate on "file_id"
My revised query taking into account what I'll need to migrate content is below:
select
original.content_id,
original.url_name_,
original.title_,
parent.id,
parent.url_name_,
parent.title_,
place_holder,
sf_object_data.caption_,
sf_control_properties.nme,
val
from [sf_page_node] original
join sf_object_data on original.content_id = sf_object_data.page_id
join sf_control_properties on sf_object_data.id = sf_control_properties.control_id
join sf_page_node parent on original.parent_id = parent.id
I hope this helps someone!
You don't need the version items in this case - as you already found out, it stores the previous version of the pages in binary format.
The current live pages' data is available in sf_control_properties and sf_object_data tables. You need to join these together with sf_page_data and sf_page_node and you will get the full picture.
Depending on your requirements, it may be easier to do a GET request to each page and parse the returned html response.

Oracle Application Express SQL Query to show meaningful information

I am trying to write a query that 1) works and 2) shows meaningful information.
However, I can't seem to complete both scenarios. Both bits of code do work to a degree. My SQL query does work by showing all the useful information a user wants but when you click the edit button it doesn't link properly so it won't allow the user to update that row. The other shows only keys and rowid but when you click edit does show the information and allows it to be updated.
So as not to get another down-voted question, I have taken pictures of each scenario to show the problem, but, ultimately, I need to show meaningful information: an id or key isn't meaningful to the vast majority of users.
Here is my code
SELECT APPLICATIONS.APP_ID, APPLICATIONS.SRN, STUDENTS.SURNAME, STUDENTS.FORENAME, APP_STATUS.STATUS, METHODS.METHOD, JOBS.JOB_TITLE, APPLICATIONS.APP_DATE
FROM APPLICATIONS
JOIN STUDENTS
ON APPLICATIONS.SRN = STUDENTS.SRN
JOIN APP_STATUS
ON APPLICATIONS.STATUS_ID = APP_STATUS.STATUS_ID
JOIN METHODS
ON APPLICATIONS.METHOD_ID = METHODS.METHOD_ID
JOIN JOBS
ON APPLICATIONS.JOB_ID = JOBS.JOB_ID;
and here are the pictures of it in action
below is the code that does not show meaningful information but does work.
select "ROWID",
"APP_ID",
"SRN",
"STATUS_ID",
"METHOD_ID",
"JOB_ID",
"APP_DATE"
from "#OWNER#"."APPLICATIONS"
If i knew how to properly use rowid i am sure this is a simple feat but i dont so if i could get any help it would be useful
//edit
who ever renamed this to Application Expression why? what i am using is Apex Application Express it was relevant information that got changed to something wrong which might make it hard for someone with a similar problem to find later.
In the second, simple query, apex can determine which table (and record) you are trying to edit.
In the first query, with the joins, it can't tell which of the five tables in query you want to edit. You probably want to have the edit link pass the primary key of the row from APPLICATIONS to the child page. You would need to build into that page any logic (lists of values etc) that map lookup tables (such as status) to the values needed in the APPLICATIONS table.

Concrete5 - unique block on every page

I have a block that displays the number of clicks on the page it is installed.
I want to display that block on every page.
I have tried creating a stack and then including that stack into a global area. The problem is that when the stack is included it includes the same block on every page.
So instead of having different blocks on every page, I have the same block on every page. That results in counting the clicks on all pages instead of only the current one.
How can I include a block on every page, but each having an unique ID as it has when added manually?
Thanks.
There's no way to have a unique block on every page without adding it manually. Even if you make it a "page type default", you'll end up with a shared block ID until you make the first edit (at which point it'll get it's own ID). And if you hardcode into the page's PHP code, it won't have a block ID at all.
With that being said, I don't know why you need a unique block ID. Obviously, each page is going to have a unique ID. So your block should be able to store clicks (I'm not sure exactly what you mean here, but it's probably irrelevant) against the page ID (collection ID in c5 parlance), and retrieve it against that, too.
Edit:
Considering your comment, and based on my understanding of what you're trying to do, there's no reason why you can't combine the block ID (which will, as you say, be duplicated across pages, but will be different on each block ON a page) and the page ID. So if you place two blocks in a stack, they'll get IDs 1 and 2. They'll have IDs 1 and 2 on every page the stack is own. So when you're trying to "record" whatever data they product, you combine the bID with the cID to get 1-103 and 2-103, and 1-4719, etc.
Edit 2:
So if your difficulty isn't so much "keying" the data, but physically storing the data, then see jordanlev's comment below. You won't be using the $btTable table as that's keyed off the bID. Instead you'll use db.xml to create a new table which can take your new key, and whatever other data you want to store. It's then your responsibility to query and update it with Loader::db(). See his block, or see the core's "survey" block for examples of how to manage your own db table.

What sort of database design would I need to use in case I wanted users to save tags, and be able to call already used tags?

I'm trying to implement a feature similar to StackOverflow's tag feature. That a user can create a new tag, or by typing pull up a list of similar tags already created.
This is such a wonderful feature on this site and I find it sad that most sites do not have something like this. It's both robust, and yet very very flexible and best of all: driven by the community.
So I have these two tables:
Company
id
email
name
companySize
countryOfOrigin
industryid
Industry
id
description
Every time a user writes a new tag, I want to create one with a unique ID, and also be able to search for existing tags.
Will this database design allow for an easy and efficient implementation of this feature?
If not, please give a little guidance. :)
Whilst there's not a tremendous amount of information to go on, what you've listed should be fine. (The 'tag' being the 'description' field in the industry table, etc.)
As you might imagine, all of the real work is done outside of SQL, where you'll need to...
(Potentially) add new tag(s) that don't yet exist.
Associate the industry with the supplied tag(s).
(Potentially) prune previously used tags that may no longer be in use.
...every time you edit an industry.
That said, the key limitation of your proposed setup is that each company can only belong to a single industry. (i.e.: It can only have a single industry tag associated with it.)
As such, you might want to consider a schema along the lines of...
Company
id
...
countryOfOrigin
Industries
id
description
CompanyIndustriesLookup
companyID
industryID
...which would let you associate multiple industries/tags with a given company.
Update...
For example, under this setup, to get all of the tags associated with company ID 1, you'd use...
SELECT Industries.description FROM (CompanyIndustriesLookup, Industries)
WHERE companyID=1 AND industryID=Industries.ID
ORDER BY Industries.description ASC;
On a similar basis, to get all companies tagged with an industry of "testing", you'd use...
SELECT Company.name FROM (Company, Industries, CompanyIndustriesLookup)
WHERE Company.id=CompanyIndustriesLookup.companyID
AND Industries.id=CompanyIndustriesLookup.industryID
AND Industries.description="testing"
ORDER BY Company.name ASC
A very easy (if somewhat suboptimal, but it often does not matter) solution to use tags is to not have tag ids at all. So, you have:
Items
ItemId
Name
Description
...
ItemTag
ItemId
Tag
Adding a tag to an item is just adding the tuple to the ItemTag table, whether the tag already exists or not. And you don't have to do any bookkeeping on removing tags either. Just keep an index on ItemTag.Tag, to be able to quickly display all unique tags.